@rokkit/core 1.0.0-next.13 → 1.0.0-next.130

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.
Files changed (91) hide show
  1. package/dist/calendar.d.ts +10 -0
  2. package/dist/colors/index.d.ts +47 -0
  3. package/dist/connector.d.ts +8 -0
  4. package/dist/constants.d.ts +88 -0
  5. package/dist/events.d.ts +12 -0
  6. package/dist/field-mapper.d.ts +60 -0
  7. package/dist/index.d.ts +13 -0
  8. package/dist/key-event-map.d.ts +18 -0
  9. package/dist/mapped-items.d.ts +14 -0
  10. package/dist/mapping.d.ts +14 -0
  11. package/dist/nested.d.ts +9 -0
  12. package/dist/string.d.ts +59 -0
  13. package/dist/theme.d.ts +96 -0
  14. package/dist/ticks.d.ts +10 -0
  15. package/dist/types.d.ts +300 -0
  16. package/dist/utils.d.ts +107 -0
  17. package/dist/vite/icon-collections.d.ts +32 -0
  18. package/dist/vite/index.d.ts +1 -0
  19. package/package.json +24 -39
  20. package/src/calendar.js +44 -0
  21. package/src/colors/extra.json +16 -0
  22. package/src/colors/syntax.json +42 -0
  23. package/src/colors/tailwind.json +275 -0
  24. package/src/connector.js +34 -0
  25. package/src/constants.js +181 -107
  26. package/src/events.js +32 -0
  27. package/src/field-mapper.js +147 -0
  28. package/src/index.js +19 -27
  29. package/src/key-event-map.js +36 -0
  30. package/src/mapped-items.js +22 -0
  31. package/src/mapping.js +21 -0
  32. package/src/nested.js +28 -0
  33. package/src/string.js +97 -0
  34. package/src/ticks.js +26 -0
  35. package/src/types.js +160 -0
  36. package/src/utils.js +250 -0
  37. package/src/vite/icon-collections.js +73 -0
  38. package/src/vite/index.js +1 -0
  39. package/LICENSE +0 -21
  40. package/README.md +0 -1
  41. package/src/Accordion.svelte +0 -80
  42. package/src/Alerts.svelte +0 -39
  43. package/src/DropDown.svelte +0 -82
  44. package/src/DropSearch.svelte +0 -67
  45. package/src/EditableTabs.svelte +0 -31
  46. package/src/Icon.svelte +0 -15
  47. package/src/List-Discard.svelte +0 -48
  48. package/src/List.svelte +0 -65
  49. package/src/ListActions.svelte +0 -35
  50. package/src/NavTabs.svelte +0 -0
  51. package/src/NestedList.svelte +0 -77
  52. package/src/Overlay.svelte +0 -4
  53. package/src/PageNavigator.svelte +0 -94
  54. package/src/ResponsiveGrid.svelte +0 -73
  55. package/src/Scrollable.svelte +0 -8
  56. package/src/Searchable.svelte +0 -19
  57. package/src/Sidebar.svelte +0 -5
  58. package/src/Slider.svelte +0 -17
  59. package/src/SpinList.svelte +0 -48
  60. package/src/SplitPane.svelte +0 -109
  61. package/src/SplitView.svelte +0 -44
  62. package/src/Splitter.svelte +0 -95
  63. package/src/TabItem.svelte +0 -27
  64. package/src/TabItems.svelte +0 -34
  65. package/src/Tabs.svelte +0 -49
  66. package/src/Tree.svelte +0 -45
  67. package/src/actions/dismissable.js +0 -24
  68. package/src/actions/fillable.js +0 -114
  69. package/src/actions/hierarchy.js +0 -189
  70. package/src/actions/index.js +0 -7
  71. package/src/actions/navigable.js +0 -43
  72. package/src/actions/navigator.js +0 -179
  73. package/src/actions/pannable.js +0 -50
  74. package/src/actions/swipeable.js +0 -56
  75. package/src/actions/themeable.js +0 -23
  76. package/src/items/Collapsible.svelte +0 -51
  77. package/src/items/Connector.svelte +0 -26
  78. package/src/items/Link.svelte +0 -18
  79. package/src/items/Node.svelte +0 -52
  80. package/src/items/Pill.svelte +0 -19
  81. package/src/items/Separator.svelte +0 -1
  82. package/src/items/Summary.svelte +0 -27
  83. package/src/items/Text.svelte +0 -21
  84. package/src/items/index.js +0 -8
  85. package/src/list.js +0 -14
  86. package/src/mocks/Custom.svelte +0 -7
  87. package/src/mocks/index.js +0 -10
  88. package/src/stores/alerts.js +0 -3
  89. package/src/stores/index.js +0 -6
  90. package/src/stores/persist.js +0 -63
  91. package/src/stores/theme.js +0 -34
package/src/utils.js ADDED
@@ -0,0 +1,250 @@
1
+ import { has, isNil } from 'ramda'
2
+ import { DATA_IMAGE_REGEX, ITEM_SNIPPET } from './constants'
3
+
4
+ let idCounter = 0
5
+
6
+ /**
7
+ * RTL language codes (ISO 639-1)
8
+ * @type {string[]}
9
+ */
10
+ const RTL_LANGUAGES = [
11
+ 'ar', // Arabic
12
+ 'he', // Hebrew
13
+ 'fa', // Persian/Farsi
14
+ 'ur', // Urdu
15
+ 'yi', // Yiddish
16
+ 'ps', // Pashto
17
+ 'sd', // Sindhi
18
+ 'ug', // Uyghur
19
+ 'ku', // Kurdish (Sorani)
20
+ 'dv' // Divehi/Maldivian
21
+ ]
22
+
23
+ /**
24
+ * Detects text direction based on HTML lang attribute
25
+ * @returns {'ltr' | 'rtl'}
26
+ */
27
+ export function detectDirection() {
28
+ if (typeof document === 'undefined') return 'ltr'
29
+
30
+ // Check dir attribute first (explicit override)
31
+ const htmlDir = document.documentElement.getAttribute('dir')
32
+ if (htmlDir === 'rtl' || htmlDir === 'ltr') return htmlDir
33
+
34
+ // Detect from lang attribute
35
+ const lang = document.documentElement.getAttribute('lang')
36
+ if (lang) {
37
+ // Extract primary language code (e.g., 'ar-SA' -> 'ar')
38
+ const primaryLang = lang.split('-')[0].toLowerCase()
39
+ if (RTL_LANGUAGES.includes(primaryLang)) return 'rtl'
40
+ }
41
+
42
+ return 'ltr'
43
+ }
44
+
45
+ /**
46
+ * Checks if current document direction is RTL
47
+ * @returns {boolean}
48
+ */
49
+ export function isRTL() {
50
+ return detectDirection() === 'rtl'
51
+ }
52
+ /**
53
+ * Finds the closest ancestor of the given element that has the given attribute.
54
+ *
55
+ * @param {HTMLElement} element
56
+ * @param {string} attribute
57
+ * @returns {HTMLElement|null}
58
+ */
59
+ export function getClosestAncestorWithAttribute(element, attribute) {
60
+ if (!element) return null
61
+ if (element.getAttribute(attribute)) return element
62
+ return getClosestAncestorWithAttribute(element.parentElement, attribute)
63
+ }
64
+
65
+ /**
66
+ * A function that performs no operations.
67
+ */
68
+ export function noop() {
69
+ // intentionally empty to support default actions
70
+ }
71
+
72
+ /**
73
+ * Generates a random id
74
+ *
75
+ * @returns {string} A random id
76
+ */
77
+ export function id(prefix = '') {
78
+ return [prefix, Math.random().toString(36).substring(2, 9), ++idCounter]
79
+ .filter((x) => !isNil(x) && x !== '')
80
+ .join('-')
81
+ }
82
+
83
+ /**
84
+ * Check if a value is a json object
85
+ *
86
+ * @param {*} val
87
+ * @returns {boolean}
88
+ */
89
+ export function isObject(val) {
90
+ return typeof val === 'object' && !isNil(val) && !(val instanceof Date)
91
+ }
92
+
93
+ /**
94
+ * Converts the value to a string. If the value is an object, it will convert it to a JSON string.
95
+ *
96
+ * @param {*} value
97
+ * @returns {string}
98
+ */
99
+ export function toString(value) {
100
+ if (value === null || value === undefined) return value
101
+ if (isObject(value)) return JSON.stringify(value, null, 2)
102
+ return value.toString()
103
+ }
104
+
105
+ /**
106
+ * Generates icon shortcuts for a collection of icons
107
+ *
108
+ * @param {string[]} icons
109
+ * @param {string} collection
110
+ * @param {string} variants
111
+ * @returns {Object}
112
+ */
113
+ export function iconShortcuts(icons, collection, variants) {
114
+ const suffix = variants ? `-${variants}` : ''
115
+ const shortcuts = !collection
116
+ ? {}
117
+ : icons.reduce(
118
+ (acc, name) => ({
119
+ ...acc,
120
+ [name]: [collection, name].join(':') + suffix
121
+ }),
122
+ {}
123
+ )
124
+
125
+ return shortcuts
126
+ }
127
+
128
+ /**
129
+ * Scales the path by the size
130
+ *
131
+ * @param {number} size
132
+ * @param {string|number} x
133
+ * @returns {string|number}
134
+ */
135
+ export function scaledPath(size, x) {
136
+ if (Array.isArray(x)) return x.map((v) => scaledPath(size, v)).join(' ')
137
+ return typeof x === 'number' ? x * size : x
138
+ }
139
+
140
+ /**
141
+ * Gets a key string from path
142
+ * @param {string[]} path
143
+ * @returns {string}
144
+ */
145
+ export function getKeyFromPath(path) {
146
+ return Array.isArray(path) ? path.join('-') : [path].join('-')
147
+ }
148
+
149
+ /**
150
+ * Gets a path array from key string
151
+ * @param {string} key
152
+ * @returns {string[]}
153
+ */
154
+ export function getPathFromKey(key) {
155
+ return key.split('-').map(Number)
156
+ }
157
+
158
+ /**
159
+ * Get snippet function from an object
160
+ * @param {Object} obj
161
+ * @param {string} key
162
+ * @param {null|Function} defaultSnippet
163
+ * @returns {Function|undefined}
164
+ */
165
+ export function getSnippet(obj, key, defaultSnippet = null) {
166
+ if (has(key, obj) && typeof obj[key] === 'function') {
167
+ return obj[key]
168
+ }
169
+ return defaultSnippet
170
+ }
171
+
172
+ /**
173
+ * Resolve which snippet to render for a proxy item.
174
+ *
175
+ * Checks proxy.snippet for a per-item named override first (e.g. item.snippet = 'highlighted').
176
+ * Falls back to the component-level fallback snippet name (e.g. 'itemContent' / 'groupContent').
177
+ * Returns null if neither is found.
178
+ *
179
+ * @param {Record<string, unknown>} snippets - snippets passed to the component
180
+ * @param {{ snippet?: string | null }} proxy - any object with an optional .snippet property
181
+ * @param {string} [fallback] - fallback snippet name; defaults to ITEM_SNIPPET ('itemContent')
182
+ * @returns {Function | null}
183
+ */
184
+ export function resolveSnippet(snippets, proxy, fallback = ITEM_SNIPPET) {
185
+ const name = proxy?.snippet
186
+ if (name && typeof snippets[name] === 'function') return snippets[name]
187
+ const fb = snippets[fallback]
188
+ return typeof fb === 'function' ? fb : null
189
+ }
190
+
191
+ /**
192
+ * convert hex string to `{r} {g} {b}`
193
+ * @param {string} hex
194
+ * @return {string}
195
+ */
196
+ export function hex2rgb(hex) {
197
+ const [r, g, b] = hex.match(/\w\w/g).map((x) => parseInt(x, 16))
198
+ return `${r},${g},${b}`
199
+ }
200
+
201
+ /**
202
+ * Checks if a string is a valid image URL
203
+ *
204
+ * @param {string} str - The string to check
205
+ * @returns {boolean} - Returns true if the string is an image URL
206
+ */
207
+ function isImageUrl(str) {
208
+ // Fallback regex-based validation
209
+ const fallbackValidation = () => {
210
+ const urlRegex = /^https?:\/\/.+\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff)(\?.*)?$/i
211
+ return urlRegex.test(str)
212
+ }
213
+
214
+ // Check if the string looks like a URL
215
+ try {
216
+ // Use browser-native URL constructor if available
217
+ if (typeof URL !== 'undefined') {
218
+ const url = new URL(str)
219
+ // Only accept HTTP/HTTPS protocols
220
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
221
+ return false
222
+ }
223
+ // Check common image extensions
224
+ const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.tiff']
225
+ const path = url.pathname.toLowerCase()
226
+ return imageExtensions.some((ext) => path.endsWith(ext))
227
+ }
228
+
229
+ // Fallback if URL constructor is not available
230
+ return fallbackValidation()
231
+
232
+ } catch {
233
+ // Fallback if URL constructor fails
234
+ return fallbackValidation()
235
+ }
236
+ }
237
+ /**
238
+ * A utility function that detects if a string is an image URL or image data (base64)
239
+ *
240
+ * @param {string} str - The string to check
241
+ * @returns {string|null} - Returns the original string if it's an image URL or image data, otherwise null
242
+ */
243
+ export function getImage(str) {
244
+ if (DATA_IMAGE_REGEX.test(str)) return str
245
+ // Check if it's a URL
246
+
247
+ if (isImageUrl(str)) return str
248
+
249
+ return null
250
+ }
@@ -0,0 +1,73 @@
1
+ import { createRequire } from 'module'
2
+ import { resolve, isAbsolute } from 'path'
3
+ import { readFileSync } from 'fs'
4
+
5
+ // Two require contexts: CWD (for site-specific packages like @iconify-json/*)
6
+ // and the module's own location (for workspace packages like @rokkit/icons).
7
+ const requireFromCwd = createRequire(resolve(process.cwd(), 'package.json'))
8
+ const requireFromModule = createRequire(import.meta.url)
9
+
10
+ function requirePackage(jsonPath) {
11
+ try {
12
+ return requireFromCwd(jsonPath)
13
+ } catch {
14
+ return requireFromModule(jsonPath)
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Creates icon collection loaders for UnoCSS presetIcons from a simple config.
20
+ *
21
+ * This function transforms a map of collection names to JSON package paths
22
+ * into the format expected by UnoCSS's presetIcons.
23
+ *
24
+ * Supports three types of paths:
25
+ * - Package paths (e.g., '@rokkit/icons/ui.json') - resolved via require
26
+ * - Absolute paths (e.g., '/path/to/icons.json') - used directly
27
+ * - Relative paths (e.g., './static/icons.json') - resolved from process.cwd()
28
+ *
29
+ * @example
30
+ * // uno.config.js
31
+ * import { iconCollections } from '@rokkit/core/vite'
32
+ *
33
+ * export default defineConfig({
34
+ * presets: [
35
+ * presetIcons({
36
+ * collections: iconCollections({
37
+ * rokkit: '@rokkit/icons/ui.json',
38
+ * logo: '@rokkit/icons/auth.json',
39
+ * solar: '@iconify-json/solar/icons.json',
40
+ * custom: './static/icons/custom.json'
41
+ * })
42
+ * })
43
+ * ]
44
+ * })
45
+ *
46
+ * @param {Record<string, string>} config - Map of collection alias to JSON path
47
+ * @returns {Record<string, () => any>} Collections object for presetIcons
48
+ */
49
+ export function iconCollections(config) {
50
+ if (!config || typeof config !== 'object') {
51
+ return {}
52
+ }
53
+
54
+ return Object.entries(config).reduce((acc, [alias, jsonPath]) => {
55
+ acc[alias] = () => {
56
+ // Check if it's a relative path (starts with ./ or ../)
57
+ if (jsonPath.startsWith('./') || jsonPath.startsWith('../')) {
58
+ // Resolve relative to current working directory (where the config is)
59
+ const absolutePath = resolve(process.cwd(), jsonPath)
60
+ return JSON.parse(readFileSync(absolutePath, 'utf-8'))
61
+ }
62
+
63
+ // Check if it's an absolute path
64
+ if (isAbsolute(jsonPath)) {
65
+ return JSON.parse(readFileSync(jsonPath, 'utf-8'))
66
+ }
67
+
68
+ // Otherwise treat as a package path; try CWD first (site packages), then module location
69
+ return requirePackage(jsonPath)
70
+ }
71
+ return acc
72
+ }, {})
73
+ }
@@ -0,0 +1 @@
1
+ export { iconCollections } from './icon-collections.js'
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2022 Jerry Thomas
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/README.md DELETED
@@ -1 +0,0 @@
1
- # Core Components
@@ -1,80 +0,0 @@
1
- <script>
2
- import { createEventDispatcher } from 'svelte'
3
- import { defaultFields } from './constants'
4
- import { Text, Summary } from './items'
5
- import List from './List.svelte'
6
- import { navigator } from './actions/navigator'
7
-
8
- const dispatch = createEventDispatcher()
9
- let className = ''
10
- export { className as class }
11
- export let items = []
12
- export let fields = {}
13
- export let using = {}
14
- export let autoClose = false
15
- export let value = null
16
- let cursor = []
17
-
18
- $: fields = { ...defaultFields, ...fields }
19
- $: using = { default: Text, ...using }
20
-
21
- function handle(event) {
22
- // console.log(event.type, event.detail)
23
- value = event.detail.node
24
- cursor = event.detail.path
25
- if (['collapse', 'expand'].includes(event.type)) {
26
- if (autoClose) {
27
- items.map((x) => {
28
- if (x !== value && x[fields.isOpen]) {
29
- x[fields.isOpen] = false
30
- }
31
- })
32
- }
33
- items = items
34
- }
35
- dispatch(event.type, event.detail)
36
- }
37
- </script>
38
-
39
- <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
40
- <accordion
41
- class="flex flex-col w-full select-none {className}"
42
- tabindex="0"
43
- use:navigator={{
44
- items,
45
- fields,
46
- enabled: true,
47
- indices: cursor
48
- }}
49
- on:select={handle}
50
- on:move={handle}
51
- on:expand={handle}
52
- on:collapse={handle}
53
- >
54
- {#each items as item, index}
55
- {@const hasItems =
56
- item[fields.children] && item[fields.children].length > 0}
57
- {@const itemFields = { ...fields, ...(fields.fields ?? fields) }}
58
-
59
- <div
60
- id={'id-' + index}
61
- class="flex flex-col"
62
- class:is-expanded={item[fields.isOpen]}
63
- class:is-selected={item === value}
64
- data-path={index}
65
- >
66
- <Summary {fields} {using} bind:content={item} />
67
- {#if hasItems && item[fields.isOpen]}
68
- <List
69
- bind:items={item[fields.children]}
70
- bind:value
71
- fields={itemFields}
72
- {using}
73
- on:select
74
- hierarchy={[index]}
75
- tabindex="-1"
76
- />
77
- {/if}
78
- </div>
79
- {/each}
80
- </accordion>
package/src/Alerts.svelte DELETED
@@ -1,39 +0,0 @@
1
- <script>
2
- import { fade } from 'svelte/transition'
3
- import { flip } from 'svelte/animate'
4
- import { alerts } from './stores'
5
- import { dismissable } from './actions'
6
-
7
- function dismissAll() {
8
- unreadAlerts.map((alert) => (alert.dismissed = true))
9
- alerts.set([...$alerts])
10
- }
11
-
12
- function dismiss(alert) {
13
- alert.dismissed = true
14
- alerts.set([...$alerts])
15
- }
16
-
17
- $: unreadAlerts = $alerts.filter((x) => x.dismissed)
18
- </script>
19
-
20
- {#if unreadAlerts.length > 0}
21
- <alert-list
22
- class="flex flex-col gap-2 absolute z-10"
23
- use:dismissable
24
- on:dismiss={dismissAll}
25
- >
26
- {#each unreadAlerts as alert (alert.id)}
27
- <!-- svelte-ignore a11y-click-events-have-key-events -->
28
- <alert
29
- class={alert.type}
30
- on:click|stopPropagation={dismiss(alert)}
31
- animate:flip
32
- in:fade
33
- out:fade
34
- >
35
- {alert.message}
36
- </alert>
37
- {/each}
38
- </alert-list>
39
- {/if}
@@ -1,82 +0,0 @@
1
- <script>
2
- import { createEventDispatcher } from 'svelte'
3
- import { dismissable } from './actions'
4
- import { defaultFields, defaultStateIcons } from './constants.js'
5
-
6
- import Icon from './Icon.svelte'
7
- import Text from './items/Text.svelte'
8
- import List from './List.svelte'
9
- import Slider from './Slider.svelte'
10
-
11
- const dispatch = createEventDispatcher()
12
-
13
- let className = ''
14
- export { className as class }
15
- export let items = []
16
- export let fields = defaultFields
17
- export let using = { default: Text }
18
- export let value = null
19
- export let title
20
- export let icon
21
- export let small = false
22
-
23
- $: using = { default: Text, ...using }
24
- $: fields = { ...defaultFields, ...fields }
25
-
26
- let offsetTop = 0
27
- let open = false
28
- let icons = defaultStateIcons.selector
29
-
30
- function handleSelect(event) {
31
- open = false
32
- dispatch('change', event.detail)
33
- }
34
- </script>
35
-
36
- <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
37
- <drop-down
38
- class="flex w-full relative cursor-pointer select-none dropdown {className}"
39
- class:open
40
- tabindex="0"
41
- aria-haspopup="true"
42
- aria-controls="menu"
43
- use:dismissable
44
- on:blur={() => (open = false)}
45
- on:dismiss={() => (open = false)}
46
- >
47
- <button
48
- on:click|stopPropagation={() => (open = !open)}
49
- class="flex"
50
- bind:clientHeight={offsetTop}
51
- tabindex="-1"
52
- >
53
- {#if icon}
54
- <Icon name={icon} />
55
- {/if}
56
- {#if !small && title}
57
- <p>{title}</p>
58
- {/if}
59
- {#if open}
60
- <icon class={icons.opened} />
61
- {:else}
62
- <icon class={icons.closed} />
63
- {/if}
64
- </button>
65
- {#if open}
66
- <!-- <div
67
- class="flex flex-col absolute z-10 h-fit w-full menu"
68
- style:top="{offsetTop}px"
69
- > -->
70
- <Slider top={offsetTop}>
71
- <List
72
- {items}
73
- {fields}
74
- {using}
75
- bind:value
76
- on:select={handleSelect}
77
- tabindex="-1"
78
- />
79
- </Slider>
80
- <!-- </div> -->
81
- {/if}
82
- </drop-down>
@@ -1,67 +0,0 @@
1
- <script>
2
- import { defaultFields } from './constants.js'
3
- import List from './List.svelte'
4
- import Slider from './Slider.svelte'
5
- import { Text } from './items'
6
-
7
- export let data
8
- export let value = null
9
- export let fields = defaultFields
10
- export let using = { default: Text }
11
-
12
- $: using = { default: Text, ...using }
13
- $: fields = { ...defaultFields, ...fields }
14
-
15
- let opened = false
16
- let search
17
- let searchBox
18
-
19
- // on search change filter list
20
- function handleSelect(event) {
21
- console.log('selected', event)
22
- value = event.detail
23
- search = event.detail[fields.text]
24
- }
25
- </script>
26
-
27
- <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
28
- <div
29
- class="flex flex-col outline-none w-full h-12 relative dropdown"
30
- tabindex={0}
31
- >
32
- <div class="flex flex-shrink-0 h-12 items-center pl-4 selected-item">
33
- <span class="flex flex-grow">
34
- <input
35
- type="text"
36
- class="p-0 border-none bg-transparent w-full"
37
- bind:value={search}
38
- bind:this={searchBox}
39
- on:focus={() => {
40
- opened = true
41
- searchBox.select()
42
- }}
43
- on:blur={() => {
44
- opened = false
45
- }}
46
- />
47
- </span>
48
- {#if opened}
49
- <icon class="selector-opened" />
50
- {:else}
51
- <icon class="selector-closed" />
52
- {/if}
53
- </div>
54
-
55
- {#if opened}
56
- <Slider>
57
- <List
58
- bind:items={data}
59
- bind:value
60
- {fields}
61
- {using}
62
- on:select={handleSelect}
63
- on:change
64
- />
65
- </Slider>
66
- {/if}
67
- </div>
@@ -1,31 +0,0 @@
1
- <script>
2
- import TabItems from './TabItems.svelte'
3
- import TabItem from './TabItem.svelte'
4
-
5
- let className = ''
6
- export { className as class }
7
- export let items = []
8
- export let fields = {}
9
- export let title = null
10
- export let allowAdd = false
11
- export let allowClose = false
12
- export let value = items[0]
13
-
14
- function addTab() {
15
- items = [...items, {}]
16
- value = items[items.length - 1]
17
- }
18
- </script>
19
-
20
- <tab-view class="flex flex-col w-full flex-grow {className}">
21
- <tabs class="flex flex-row flex-shrink-0 w-full select-none cursor-pointer">
22
- {#if title}
23
- <p>{title}</p>
24
- {/if}
25
- <TabItems {items} {fields} {allowClose} bind:value on:close />
26
- {#if allowAdd}
27
- <TabItem label="+" on:click={addTab} />
28
- {/if}
29
- </tabs>
30
- <content class="flex flex-col flex-grow"><slot /></content>
31
- </tab-view>
package/src/Icon.svelte DELETED
@@ -1,15 +0,0 @@
1
- <script>
2
- let className = ''
3
- export { className as class }
4
-
5
- export let name = ''
6
- let h
7
- </script>
8
-
9
- <square-icon
10
- class="flex flex-col flex-shrink-0 h-full items-center justify-center {className}"
11
- bind:clientHeight={h}
12
- style:width="{h}px"
13
- >
14
- <icon class={name} aria-hidden="true" />
15
- </square-icon>