Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardized collapsible component #518

Merged
merged 36 commits into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5fe699e
basic collapsible component
rsek Oct 21, 2022
90ffcbb
add FA6 font to overrides
rsek Oct 22, 2022
6cfc2a3
rewrite sf-moverow as collapsible
rsek Oct 22, 2022
a885f43
replace hover fx
rsek Oct 22, 2022
670c4bf
add toggleTooltip
rsek Oct 22, 2022
ec69273
further presentation refinements
rsek Oct 22, 2022
1bca407
fancy move category accordions with theme colors
rsek Oct 22, 2022
c0ed3a8
Update src/module/vue/components/buttons/btn-sendmovetochat.vue
rsek Oct 23, 2022
6fa89fe
incremental progress (jump links broken)
rsek Oct 23, 2022
dfdc80a
move fake stroke to mixins
rsek Oct 23, 2022
d944fcf
additional refinements, links still broken
rsek Oct 23, 2022
e388eba
style adjustments/experimentation
rsek Oct 24, 2022
fef8cec
add luminance utility function
rsek Oct 24, 2022
9c10f5e
patch in correct move colours
rsek Oct 24, 2022
69ca12b
adjust props; less ambiguous + animated chevron
rsek Oct 24, 2022
62d81c0
ironsworn fallback colors
rsek Oct 24, 2022
a2ffcd4
minor adjustments
rsek Oct 24, 2022
ca6e60b
reorganize move category keys
rsek Oct 24, 2022
1696c65
missing move categories; simple alt move handling
rsek Oct 24, 2022
0d45a0d
adjust comment
rsek Oct 27, 2022
94a9698
Merge remote-tracking branch 'upstream/main' into collapsibles
rsek Oct 27, 2022
0f69d5e
Move item fn: isProgressMove
rsek Oct 27, 2022
253291c
mv search colors, fix jump link
rsek Oct 27, 2022
bb1825c
progress move label
rsek Oct 27, 2022
fda0a82
comment cleanup
rsek Nov 22, 2022
b7e9c00
Merge branch 'main' into collapsibles
rsek Nov 22, 2022
3ab5b1d
fix text outline colors
rsek Nov 22, 2022
37bd16a
apply category colours to search results
rsek Nov 22, 2022
c586a18
sf theme fixes
rsek Nov 23, 2022
ba3cbf9
fixes to button alignment
rsek Nov 23, 2022
5c9b54b
nudge scrollbar for FF
rsek Nov 23, 2022
087bc58
Update util.ts
rsek Nov 23, 2022
cef163d
Update util.ts
rsek Nov 23, 2022
c592822
rm unneeded square brackets for prop
rsek Nov 23, 2022
e11c112
Update src/module/item/item.ts
rsek Nov 24, 2022
b66388a
Woops imports
ben Nov 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/module/vue/components/buttons/btn-sendmovetochat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,32 @@
<btn-faicon
class="move-chat"
icon="comment"
:tooltip="$t('IRONSWORN.SendToChat')"
:tooltip="$t('IRONSWORN.SendToChat', { move: move.displayName })"
@click="sendToChat"
:disabled="disabled"
>
<slot name="default"><!-- {{$t('IRONSWORN.Chat')}} --></slot>
<slot name="default"></slot>
</btn-faicon>
</template>

<style lang="less"></style>

<script setup lang="ts">
import { inject } from 'vue'
import { createSfMoveChatMessage } from '../../../chat/sf-move-chat-message'
import { Move } from '../../../features/custommoves'
import { IronswornItem } from '../../../item/item.js'
import { $ItemKey } from '../../provisions.js'
import btnFaicon from './btn-faicon.vue'

const props = defineProps<{
move: Move
disabled?: boolean
}>()

const $item = inject($ItemKey)

function sendToChat(e) {
createSfMoveChatMessage(props.move.moveItem())
createSfMoveChatMessage($item as IronswornItem)
rsek marked this conversation as resolved.
Show resolved Hide resolved
}
</script>
175 changes: 175 additions & 0 deletions src/module/vue/components/collapsible/collapsible.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<template>
<component
:id="wrapperId"
:is="wrapperIs"
:class="`${$style.collapsible} ${state.highlighted ? 'highlighted' : ''}`"
:aria-expanded="state.expanded"
:tabindex="-1"
ref="$wrapper"
>
<header :class="{ [$style.header]: true, [headerClass]: true }">
<slot name="before-toggle"></slot>
<component
:class="{ [headingClass]: true, [$style.heading]: true }"
:is="`h${headingLevel}`"
>
<component
:is="noIcon ? 'button' : BtnFaicon"
:id="controlId"
type="button"
:aria-controls="contentId"
:icon="
noIcon
? undefined
: state.expanded
? toggleIconExpanded
: toggleIconCollapsed
"
@click="toggle"
class="text clickable"
:class="{ [$style.toggle]: true, [toggleClass]: true }"
:data-tooltip="toggleTooltip"
>
<slot name="toggle-content"></slot>
</component>
</component>
<slot name="after-toggle"></slot>
</header>
<CollapseTransition>
<component
v-if="state.expanded"
:is="contentWrapperIs"
role="region"
:aria-labelledby="controlId"
:id="contentId"
class="collapsible-content"
:class="{ [contentWrapperClass]: true, [$style.contentWrapper]: true }"
>
<slot></slot>
</component>
</CollapseTransition>
</component>
</template>

<style lang="less" module>
// TODO: horizontal and vertical versions
.collapsible {
}

.contentWrapper {
padding: 0.25em 0.5rem 0.5rem;
}

.heading {
display: contents !important;
}

.toggle {
margin: 0;
height: inherit;
flex-grow: 1;
text-transform: uppercase;
justify-content: left;
font-size: inherit;
}
</style>

<script setup lang="ts">
import { nextTick, reactive } from 'vue'
import CollapseTransition from '../transition/collapse-transition.vue'
import BtnFaicon from '../buttons/btn-faicon.vue'
import { computed, ref } from '@vue/reactivity'

const props = withDefaults(
defineProps<{
/**
* The ID to be assigned to the wrapper element, from which the IDs of other elements within this component are generated. Required in order to generate the correct ARIA annotations.
*/
baseId: string
noIcon?: boolean
toggleIconCollapsed?: string
toggleIconExpanded?: string
contentWrapperIs?: string
contentWrapperClass?: any
toggleClass?: any
wrapperIs?: string
disabled?: boolean
headerClass?: any
headingLevel?: number
headingClass?: any
toggleTooltip?: string
forceExpand?: boolean
}>(),
{
toggleIconCollapsed: 'caret-right',
toggleIconExpanded: 'caret-down',
wrapperIs: 'article',
contentWrapperIs: 'section',
disabled: false,
headingLevel: 3,
}
)

const $wrapper = ref<HTMLElement>()
const state = reactive<{
forceExpand: boolean
expanded: boolean
highlighted: boolean
}>({
forceExpand: props.forceExpand ?? false,
expanded: false,
highlighted: false,
})

const wrapperId = computed(() => props.baseId)
const controlId = computed(() => `${props.baseId}_control`)
const contentId = computed(() => `${props.baseId}_content`)

function toggle() {
state.expanded = !state.expanded
}

function expand() {
state.expanded = true
}
function collapse() {
state.expanded = false
}

function highlight() {
state.highlighted = true
}

function unhighlight() {
state.highlighted = false
}

/**
* Scroll to the collapsible, apply the highlight class, and expand it.
* @param ms The duration of the highlight effect, in milliseconds
*/
async function scrollToAndExpand(ms: number = 2000) {
expand()
highlight()

await nextTick()

$wrapper.value?.scrollIntoView({
behavior: 'smooth',
block: 'start',
})

await nextTick()

setTimeout(unhighlight, ms)
}

defineExpose({
scrollToAndExpand,
unhighlight,
highlight,
toggle,
collapse,
expand,
})
</script>
86 changes: 86 additions & 0 deletions src/module/vue/components/sf-move-category-rows.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<template>
<article class="nogrow" :class="$style.wrapper">
<component
:is="`h${headingLevel}`"
:class="$style.heading"
:data-tooltip="$enrichMarkdown(category.dataforgedCategory?.Description)"
rsek marked this conversation as resolved.
Show resolved Hide resolved
data-tooltip-direction="LEFT"
>
{{ category.displayName }}
</component>
<ul class="flexcol" :class="$style.list">
<li
v-for="(move, i) of category.moves"
:key="i"
class="nogrow"
:class="$style['list-item']"
>
<SfMoverow
:move="move"
ref="allmoves"
:headingLevel="headingLevel + 1"
/>
</li>
</ul>
</article>
</template>

<style lang="less" module>
// TODO: have the custom moves pull their color from their directory
.wrapper {
border-width: 2px;
border-style: solid;
border-radius: 5px;
border-color: v-bind('category.dataforgedCategory?.Display.Color');
}

.list {
display: flex;
flex-flow: column nowrap;
list-style: none;
margin: 0;
padding: 0;
}

.list-item {
border-color: var(--ironsworn-color-border);
border-style: outset;
border-width: 0;

&:not(:first-child) {
border-top-width: 1px;
}
}
.heading {
margin: 0;
border: 0;
padding: 3px;
background-color: v-bind('category.dataforgedCategory?.Display.Color');
color: white;
}
</style>
<script setup lang="ts">
import { ref } from 'vue'
import { MoveCategory } from '../../features/custommoves.js'
import SfMoverow from './sf-moverow.vue'

const props = withDefaults(
defineProps<{
category: MoveCategory
headingLevel?: number
}>(),
{ headingLevel: 3 }
)

let allmoves = ref<InstanceType<typeof SfMoverow>[]>([])

function collapseChildren() {
for (const row of allmoves.value ?? []) {
row.collapsible?.collapse()
}
}

defineExpose({
collapseChildren,
})
</script>
Loading