@rokkit/ui 1.0.0-next.99 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -1
- package/package.json +52 -53
- package/src/MarkdownRenderer.svelte +106 -0
- package/src/components/AlertList.svelte +59 -0
- package/src/components/Avatar.svelte +68 -0
- package/src/components/Badge.svelte +57 -0
- package/src/components/BreadCrumbs.svelte +94 -0
- package/src/components/Button.svelte +91 -0
- package/src/components/ButtonGroup.svelte +9 -0
- package/src/components/Card.svelte +71 -0
- package/src/components/Carousel.svelte +169 -0
- package/src/components/Code.svelte +189 -0
- package/src/components/Connector.svelte +46 -0
- package/src/components/Divider.svelte +24 -0
- package/src/components/Dropdown.svelte +202 -0
- package/src/components/FloatingAction.svelte +367 -0
- package/src/components/FloatingNavigation.svelte +256 -0
- package/src/components/Grid.svelte +128 -0
- package/src/components/ItemContent.svelte +25 -0
- package/src/components/LazyTree.svelte +171 -0
- package/src/components/List.svelte +224 -0
- package/src/components/Menu.svelte +270 -0
- package/src/components/Message.svelte +75 -0
- package/src/components/MultiSelect.svelte +367 -0
- package/src/components/NavContent.svelte +42 -0
- package/src/components/PaletteManager.svelte +360 -0
- package/src/components/Pill.svelte +83 -0
- package/src/components/ProgressBar.svelte +31 -0
- package/src/components/Range.svelte +346 -0
- package/src/components/Rating.svelte +115 -0
- package/src/components/ResponsiveGrid.svelte +34 -0
- package/src/components/Reveal.svelte +46 -0
- package/src/components/SearchFilter.svelte +88 -0
- package/src/components/Select.svelte +424 -0
- package/src/components/Shine.svelte +87 -0
- package/src/components/Stack.svelte +38 -0
- package/src/components/StatusList.svelte +18 -0
- package/src/components/Stepper.svelte +174 -0
- package/src/components/Swatch.svelte +102 -0
- package/src/components/Switch.svelte +71 -0
- package/src/components/Table.svelte +245 -0
- package/src/components/Tabs.svelte +202 -0
- package/src/components/Tilt.svelte +68 -0
- package/src/components/Timeline.svelte +61 -0
- package/src/components/Toggle.svelte +93 -0
- package/src/components/Toolbar.svelte +306 -0
- package/src/components/ToolbarGroup.svelte +17 -0
- package/src/components/Tooltip.svelte +121 -0
- package/src/components/Tree.svelte +143 -0
- package/src/components/UploadFileStatus.svelte +102 -0
- package/src/components/UploadProgress.svelte +127 -0
- package/src/components/UploadTarget.svelte +126 -0
- package/src/components/index.ts +50 -0
- package/src/index.ts +61 -0
- package/src/markdown-plugin.ts +12 -0
- package/src/types/button.ts +86 -0
- package/src/types/code.ts +46 -0
- package/src/types/floating-action.ts +123 -0
- package/src/types/floating-navigation.ts +80 -0
- package/src/types/index.ts +58 -0
- package/src/types/list.ts +200 -0
- package/src/types/menu.ts +95 -0
- package/src/types/palette.ts +160 -0
- package/src/types/range.ts +51 -0
- package/src/types/search-filter.ts +67 -0
- package/src/types/select.ts +176 -0
- package/src/types/switch.ts +68 -0
- package/src/types/table.ts +219 -0
- package/src/types/tabs.ts +103 -0
- package/src/types/timeline.ts +53 -0
- package/src/types/toggle.ts +68 -0
- package/src/types/toolbar.ts +167 -0
- package/src/types/tooltip.ts +21 -0
- package/src/types/tree.ts +250 -0
- package/src/types/upload-file-status.ts +45 -0
- package/src/types/upload-progress.ts +111 -0
- package/src/types/upload-target.ts +71 -0
- package/src/utils/palette.ts +618 -0
- package/src/utils/shiki.ts +114 -0
- package/src/utils/upload.js +145 -0
- package/LICENSE +0 -21
- package/src/index.js +0 -8
- package/src/wrappers.js +0 -2
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Tabs — Wrapper + Navigator + ProxyItem implementation.
|
|
4
|
+
*
|
|
5
|
+
* Architecture:
|
|
6
|
+
* Wrapper — owns focusedKey $state + flatView $derived
|
|
7
|
+
* Navigator — attaches DOM event handlers, calls wrapper[action](path)
|
|
8
|
+
* owns focus + scrollIntoView after every keyboard action
|
|
9
|
+
* flatView loop — single flat {#each} for tab triggers
|
|
10
|
+
*
|
|
11
|
+
* Snippet customization:
|
|
12
|
+
* itemContent — replaces inner content of <button> for tab triggers
|
|
13
|
+
* tabPanel — replaces panel content
|
|
14
|
+
* [named] — per-item override via item.snippet = 'name'; falls back to itemContent
|
|
15
|
+
* empty — rendered when no options
|
|
16
|
+
*
|
|
17
|
+
* Tab panels are rendered separately from triggers. Only the active panel
|
|
18
|
+
* receives data-panel-active. Navigator ignores panels (no data-path on them).
|
|
19
|
+
*/
|
|
20
|
+
// @ts-nocheck
|
|
21
|
+
import type { TabsProps } from '../types/tabs.js'
|
|
22
|
+
import type { ProxyItem } from '@rokkit/states'
|
|
23
|
+
import { Wrapper, ProxyTree, messages } from '@rokkit/states'
|
|
24
|
+
import { Navigator } from '@rokkit/actions'
|
|
25
|
+
import { resolveSnippet, ITEM_SNIPPET, DEFAULT_STATE_ICONS } from '@rokkit/core'
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
options = [],
|
|
29
|
+
fields: userFields = {},
|
|
30
|
+
value = $bindable(),
|
|
31
|
+
orientation = 'horizontal',
|
|
32
|
+
position = 'before',
|
|
33
|
+
align = 'start',
|
|
34
|
+
name = 'tabs',
|
|
35
|
+
editable = false,
|
|
36
|
+
placeholder = messages.tabs.placeholder,
|
|
37
|
+
disabled = false,
|
|
38
|
+
labels: userLabels = {},
|
|
39
|
+
class: className = '',
|
|
40
|
+
onchange,
|
|
41
|
+
onselect,
|
|
42
|
+
onadd,
|
|
43
|
+
onremove,
|
|
44
|
+
...snippets
|
|
45
|
+
}: TabsProps & { labels?: Record<string, string>; [key: string]: unknown } = $props()
|
|
46
|
+
|
|
47
|
+
const labels = $derived({ ...messages.tabs, ...userLabels })
|
|
48
|
+
|
|
49
|
+
// ─── Wrapper ──────────────────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
const proxyTree = $derived(new ProxyTree(options, userFields))
|
|
52
|
+
const wrapper = $derived(
|
|
53
|
+
new Wrapper(proxyTree, {
|
|
54
|
+
onchange,
|
|
55
|
+
onselect: (v, proxy) => {
|
|
56
|
+
value = v
|
|
57
|
+
onselect?.(v, proxy)
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
// ─── Navigator ────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
let containerRef = $state<HTMLElement | null>(null)
|
|
65
|
+
|
|
66
|
+
$effect(() => {
|
|
67
|
+
if (!containerRef) return
|
|
68
|
+
const nav = new Navigator(containerRef, wrapper, { orientation })
|
|
69
|
+
return () => nav.destroy()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// ─── Sync external value → focused key ────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
$effect(() => {
|
|
75
|
+
wrapper.moveToValue(value)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// ─── Editable handlers ────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
function handleAdd() {
|
|
81
|
+
onadd?.()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function handleRemove(proxy: ProxyItem) {
|
|
85
|
+
onremove?.(proxy.value)
|
|
86
|
+
}
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
{#snippet defaultTabContent(proxy: ProxyItem)}
|
|
90
|
+
{#if proxy.get('icon')}
|
|
91
|
+
<span data-tabs-icon class={proxy.get('icon')} aria-hidden="true"></span>
|
|
92
|
+
{/if}
|
|
93
|
+
<span data-tabs-label>{proxy.label}</span>
|
|
94
|
+
{#if editable}
|
|
95
|
+
<span
|
|
96
|
+
data-tabs-remove
|
|
97
|
+
role="button"
|
|
98
|
+
tabindex="-1"
|
|
99
|
+
aria-label={labels.remove}
|
|
100
|
+
onclick={(e) => {
|
|
101
|
+
e.stopPropagation()
|
|
102
|
+
handleRemove(proxy)
|
|
103
|
+
}}
|
|
104
|
+
onkeydown={(e) => {
|
|
105
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
106
|
+
e.stopPropagation()
|
|
107
|
+
e.preventDefault()
|
|
108
|
+
handleRemove(proxy)
|
|
109
|
+
}
|
|
110
|
+
}}
|
|
111
|
+
>
|
|
112
|
+
<span class={DEFAULT_STATE_ICONS.action.close} aria-hidden="true"></span>
|
|
113
|
+
</span>
|
|
114
|
+
{/if}
|
|
115
|
+
{/snippet}
|
|
116
|
+
|
|
117
|
+
{#snippet defaultPanel(proxy: ProxyItem)}
|
|
118
|
+
<div data-tabs-content>
|
|
119
|
+
{proxy.get('content')}
|
|
120
|
+
</div>
|
|
121
|
+
{/snippet}
|
|
122
|
+
|
|
123
|
+
{#snippet defaultEmpty()}
|
|
124
|
+
No tabs available.
|
|
125
|
+
{/snippet}
|
|
126
|
+
|
|
127
|
+
<div
|
|
128
|
+
bind:this={containerRef}
|
|
129
|
+
data-tabs
|
|
130
|
+
data-orientation={orientation}
|
|
131
|
+
data-position={position}
|
|
132
|
+
data-align={align}
|
|
133
|
+
data-disabled={disabled || undefined}
|
|
134
|
+
class={className || undefined}
|
|
135
|
+
aria-label={name}
|
|
136
|
+
>
|
|
137
|
+
{#if options.length === 0}
|
|
138
|
+
<div data-tabs-empty>
|
|
139
|
+
{#if snippets.empty}
|
|
140
|
+
{@render snippets.empty()}
|
|
141
|
+
{:else}
|
|
142
|
+
{@render defaultEmpty()}
|
|
143
|
+
{/if}
|
|
144
|
+
</div>
|
|
145
|
+
{:else}
|
|
146
|
+
<div data-tabs-list role="tablist" aria-orientation={orientation}>
|
|
147
|
+
{#each wrapper.flatView as node (node.key)}
|
|
148
|
+
{@const proxy = node.proxy}
|
|
149
|
+
{@const sel = proxy.value === value}
|
|
150
|
+
{@const content = resolveSnippet(snippets, proxy, ITEM_SNIPPET)}
|
|
151
|
+
|
|
152
|
+
<button
|
|
153
|
+
type="button"
|
|
154
|
+
data-tabs-trigger
|
|
155
|
+
data-path={node.key}
|
|
156
|
+
data-selected={sel || undefined}
|
|
157
|
+
data-disabled={proxy.disabled || undefined}
|
|
158
|
+
role="tab"
|
|
159
|
+
aria-selected={sel}
|
|
160
|
+
aria-label={proxy.get('label') || proxy.label}
|
|
161
|
+
disabled={proxy.disabled || disabled}
|
|
162
|
+
>
|
|
163
|
+
{#if content}
|
|
164
|
+
{@render content(proxy, sel)}
|
|
165
|
+
{:else}
|
|
166
|
+
{@render defaultTabContent(proxy)}
|
|
167
|
+
{/if}
|
|
168
|
+
</button>
|
|
169
|
+
{/each}
|
|
170
|
+
{#if editable}
|
|
171
|
+
<button type="button" data-tabs-add aria-label={labels.add} onclick={handleAdd}>
|
|
172
|
+
<span class="i-lucide:plus" aria-hidden="true"></span>
|
|
173
|
+
</button>
|
|
174
|
+
{/if}
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
{#each wrapper.flatView as node (node.key)}
|
|
178
|
+
{@const proxy = node.proxy}
|
|
179
|
+
{@const active = proxy.value === value}
|
|
180
|
+
|
|
181
|
+
<div
|
|
182
|
+
data-tabs-panel
|
|
183
|
+
data-panel-active={active || undefined}
|
|
184
|
+
role="tabpanel"
|
|
185
|
+
id="tab-panel-{node.key}"
|
|
186
|
+
aria-labelledby="tab-{node.key}"
|
|
187
|
+
>
|
|
188
|
+
{#if snippets.tabPanel}
|
|
189
|
+
{@render snippets.tabPanel(proxy)}
|
|
190
|
+
{:else}
|
|
191
|
+
{@render defaultPanel(proxy)}
|
|
192
|
+
{/if}
|
|
193
|
+
</div>
|
|
194
|
+
{/each}
|
|
195
|
+
|
|
196
|
+
{#if value === undefined}
|
|
197
|
+
<div data-tabs-placeholder>
|
|
198
|
+
{placeholder}
|
|
199
|
+
</div>
|
|
200
|
+
{/if}
|
|
201
|
+
{/if}
|
|
202
|
+
</div>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte'
|
|
3
|
+
|
|
4
|
+
interface TiltProps {
|
|
5
|
+
/** Maximum rotation angle in degrees (default: 10) */
|
|
6
|
+
maxRotation?: number
|
|
7
|
+
/** Whether to adjust brightness based on mouse Y position */
|
|
8
|
+
setBrightness?: boolean
|
|
9
|
+
/** CSS perspective value in pixels (default: 600) */
|
|
10
|
+
perspective?: number
|
|
11
|
+
/** Additional CSS class */
|
|
12
|
+
class?: string
|
|
13
|
+
children?: Snippet
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
maxRotation = 10,
|
|
18
|
+
setBrightness = false,
|
|
19
|
+
perspective = 600,
|
|
20
|
+
class: className = '',
|
|
21
|
+
children
|
|
22
|
+
}: TiltProps = $props()
|
|
23
|
+
|
|
24
|
+
let width = $state(0)
|
|
25
|
+
let height = $state(0)
|
|
26
|
+
|
|
27
|
+
let rotateX = $state(0)
|
|
28
|
+
let rotateY = $state(0)
|
|
29
|
+
let brightness = $state(1)
|
|
30
|
+
|
|
31
|
+
/** Linear interpolation: maps value from [0, max] to [rangeMin, rangeMax] */
|
|
32
|
+
function lerp(value: number, max: number, rangeMin: number, rangeMax: number): number {
|
|
33
|
+
if (max === 0) return rangeMin
|
|
34
|
+
return rangeMin + (value / max) * (rangeMax - rangeMin)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function onMouseMove(e: MouseEvent) {
|
|
38
|
+
rotateY = lerp(e.offsetX, width, maxRotation, -maxRotation)
|
|
39
|
+
rotateX = lerp(e.offsetY, height, -maxRotation, maxRotation)
|
|
40
|
+
|
|
41
|
+
if (setBrightness) {
|
|
42
|
+
brightness = lerp(e.offsetY, height, 2.0, 1.0)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function onMouseLeave() {
|
|
47
|
+
rotateX = 0
|
|
48
|
+
rotateY = 0
|
|
49
|
+
brightness = 1
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
54
|
+
<div
|
|
55
|
+
data-tilt
|
|
56
|
+
data-tilt-brightness={setBrightness || undefined}
|
|
57
|
+
class={className || undefined}
|
|
58
|
+
style:--tilt-perspective="{perspective}px"
|
|
59
|
+
style:--tilt-rotate-x="{rotateX}deg"
|
|
60
|
+
style:--tilt-rotate-y="{rotateY}deg"
|
|
61
|
+
style:--tilt-brightness={brightness}
|
|
62
|
+
bind:clientWidth={width}
|
|
63
|
+
bind:clientHeight={height}
|
|
64
|
+
onmousemove={onMouseMove}
|
|
65
|
+
onmouseleave={onMouseLeave}
|
|
66
|
+
>
|
|
67
|
+
{@render children?.()}
|
|
68
|
+
</div>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { TimelineProps } from '../types/timeline.js'
|
|
3
|
+
import { defaultTimelineFields, defaultTimelineIcons } from '../types/timeline.js'
|
|
4
|
+
import { ProxyItem } from '@rokkit/states'
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
items = [],
|
|
8
|
+
fields: userFields,
|
|
9
|
+
icons: userIcons,
|
|
10
|
+
class: className = '',
|
|
11
|
+
content
|
|
12
|
+
}: TimelineProps = $props()
|
|
13
|
+
|
|
14
|
+
const fields = $derived({ ...defaultTimelineFields, ...userFields })
|
|
15
|
+
const icons = $derived({ ...defaultTimelineIcons, ...userIcons })
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<div data-timeline class={className || undefined} role="list">
|
|
19
|
+
{#each items as item, index (index)}
|
|
20
|
+
{@const proxy = new ProxyItem(item, fields)}
|
|
21
|
+
{@const text = proxy.label}
|
|
22
|
+
{@const icon = proxy.get('icon')}
|
|
23
|
+
{@const description = proxy.get('subtext')}
|
|
24
|
+
{@const completed = Boolean(item.completed)}
|
|
25
|
+
{@const active = Boolean(item.active)}
|
|
26
|
+
|
|
27
|
+
<div
|
|
28
|
+
data-timeline-item
|
|
29
|
+
data-completed={completed || undefined}
|
|
30
|
+
data-active={active || undefined}
|
|
31
|
+
role="listitem"
|
|
32
|
+
>
|
|
33
|
+
<div data-timeline-marker aria-hidden="true">
|
|
34
|
+
<div data-timeline-circle>
|
|
35
|
+
{#if completed}
|
|
36
|
+
<span class={icons.completed}></span>
|
|
37
|
+
{:else if icon}
|
|
38
|
+
<span class={icon}></span>
|
|
39
|
+
{:else}
|
|
40
|
+
{index + 1}
|
|
41
|
+
{/if}
|
|
42
|
+
</div>
|
|
43
|
+
{#if index < items.length - 1}
|
|
44
|
+
<div data-timeline-connector></div>
|
|
45
|
+
{/if}
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div data-timeline-body>
|
|
49
|
+
{#if text}
|
|
50
|
+
<div data-timeline-title>{text}</div>
|
|
51
|
+
{/if}
|
|
52
|
+
{#if description}
|
|
53
|
+
<div data-timeline-description>{description}</div>
|
|
54
|
+
{/if}
|
|
55
|
+
{#if content}
|
|
56
|
+
{@render content(item, index)}
|
|
57
|
+
{/if}
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
{/each}
|
|
61
|
+
</div>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import type { ToggleProps } from '../types/toggle.js'
|
|
4
|
+
import { Wrapper, ProxyTree, messages } from '@rokkit/states'
|
|
5
|
+
import { Navigator } from '@rokkit/actions'
|
|
6
|
+
import { resolveSnippet } from '@rokkit/core'
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
options = [],
|
|
10
|
+
fields: userFields = {},
|
|
11
|
+
value = $bindable(),
|
|
12
|
+
onchange,
|
|
13
|
+
showLabels = true,
|
|
14
|
+
size = 'md',
|
|
15
|
+
disabled = false,
|
|
16
|
+
label = messages.toggle.label,
|
|
17
|
+
class: className = '',
|
|
18
|
+
...snippets
|
|
19
|
+
}: ToggleProps & { [key: string]: unknown } = $props()
|
|
20
|
+
|
|
21
|
+
// ─── Wrapper ──────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
const proxyTree = $derived(new ProxyTree(options, userFields))
|
|
24
|
+
const wrapper = $derived(new Wrapper(proxyTree, { onselect: handleSelect }))
|
|
25
|
+
|
|
26
|
+
// ─── Navigator (horizontal, always attached) ───────────────────────────────
|
|
27
|
+
|
|
28
|
+
let containerRef = $state<HTMLElement | null>(null)
|
|
29
|
+
|
|
30
|
+
$effect(() => {
|
|
31
|
+
if (!containerRef) return
|
|
32
|
+
const dir = getComputedStyle(containerRef).direction
|
|
33
|
+
const nav = new Navigator(containerRef, wrapper, { orientation: 'horizontal', dir })
|
|
34
|
+
return () => nav.destroy()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// ─── Sync external value → focused key ────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
$effect(() => {
|
|
40
|
+
wrapper.moveToValue(value)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// ─── Selection handler ─────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
function handleSelect(extractedValue, proxy) {
|
|
46
|
+
if (proxy.disabled || disabled) return
|
|
47
|
+
if (extractedValue !== value) {
|
|
48
|
+
value = extractedValue
|
|
49
|
+
onchange?.(extractedValue, proxy.original)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<div
|
|
55
|
+
bind:this={containerRef}
|
|
56
|
+
data-toggle
|
|
57
|
+
data-toggle-size={size}
|
|
58
|
+
data-toggle-disabled={disabled || undefined}
|
|
59
|
+
data-toggle-labels={showLabels || undefined}
|
|
60
|
+
class={className || undefined}
|
|
61
|
+
role="radiogroup"
|
|
62
|
+
aria-label={label}
|
|
63
|
+
aria-disabled={disabled || undefined}
|
|
64
|
+
>
|
|
65
|
+
{#each wrapper.flatView as node (node.key)}
|
|
66
|
+
{@const proxy = node.proxy}
|
|
67
|
+
{@const sel = proxy.value === value}
|
|
68
|
+
{@const content = resolveSnippet(snippets, proxy)}
|
|
69
|
+
<button
|
|
70
|
+
type="button"
|
|
71
|
+
data-toggle-option
|
|
72
|
+
data-path={node.key}
|
|
73
|
+
data-selected={sel || undefined}
|
|
74
|
+
data-disabled={proxy.disabled || undefined}
|
|
75
|
+
role="radio"
|
|
76
|
+
aria-checked={sel}
|
|
77
|
+
aria-label={proxy.label}
|
|
78
|
+
title={proxy.get('description') || proxy.label}
|
|
79
|
+
disabled={proxy.disabled || disabled}
|
|
80
|
+
>
|
|
81
|
+
{#if content}
|
|
82
|
+
{@render content(proxy, sel)}
|
|
83
|
+
{:else}
|
|
84
|
+
{#if proxy.get('icon')}
|
|
85
|
+
<span data-toggle-icon class={proxy.get('icon')} aria-hidden="true"></span>
|
|
86
|
+
{/if}
|
|
87
|
+
{#if showLabels && proxy.label}
|
|
88
|
+
<span data-toggle-label>{proxy.label}</span>
|
|
89
|
+
{/if}
|
|
90
|
+
{/if}
|
|
91
|
+
</button>
|
|
92
|
+
{/each}
|
|
93
|
+
</div>
|