@rokkit/core 1.0.0-next.15 → 1.0.0-next.150

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 (93) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +121 -1
  3. package/dist/calendar.d.ts +10 -0
  4. package/dist/colors/index.d.ts +47 -0
  5. package/dist/connector.d.ts +8 -0
  6. package/dist/constants.d.ts +80 -0
  7. package/dist/events.d.ts +12 -0
  8. package/dist/field-mapper.d.ts +60 -0
  9. package/dist/index.d.ts +13 -0
  10. package/dist/key-event-map.d.ts +18 -0
  11. package/dist/mapped-items.d.ts +14 -0
  12. package/dist/mapping.d.ts +14 -0
  13. package/dist/nested.d.ts +9 -0
  14. package/dist/string.d.ts +59 -0
  15. package/dist/theme.d.ts +96 -0
  16. package/dist/ticks.d.ts +10 -0
  17. package/dist/types.d.ts +300 -0
  18. package/dist/utils.d.ts +104 -0
  19. package/dist/vite/icon-collections.d.ts +32 -0
  20. package/dist/vite/index.d.ts +1 -0
  21. package/package.json +31 -39
  22. package/src/calendar.js +44 -0
  23. package/src/colors/extra.json +16 -0
  24. package/src/colors/index.ts +24 -0
  25. package/src/colors/syntax.json +42 -0
  26. package/src/colors/tailwind.json +275 -0
  27. package/src/connector.js +34 -0
  28. package/src/constants.js +163 -107
  29. package/src/events.js +32 -0
  30. package/src/field-mapper.js +147 -0
  31. package/src/index.js +19 -27
  32. package/src/key-event-map.js +35 -0
  33. package/src/mapped-items.js +22 -0
  34. package/src/mapping.js +21 -0
  35. package/src/nested.js +28 -0
  36. package/src/string.js +97 -0
  37. package/src/theme.ts +208 -0
  38. package/src/ticks.js +26 -0
  39. package/src/types.js +160 -0
  40. package/src/utils.js +272 -0
  41. package/src/vite/icon-collections.js +73 -0
  42. package/src/vite/index.js +1 -0
  43. package/src/Accordion.svelte +0 -80
  44. package/src/Alerts.svelte +0 -39
  45. package/src/DropDown.svelte +0 -82
  46. package/src/DropSearch.svelte +0 -67
  47. package/src/EditableTabs.svelte +0 -31
  48. package/src/Icon.svelte +0 -15
  49. package/src/List-Discard.svelte +0 -48
  50. package/src/List.svelte +0 -65
  51. package/src/ListActions.svelte +0 -35
  52. package/src/NavTabs.svelte +0 -0
  53. package/src/NestedList.svelte +0 -77
  54. package/src/Overlay.svelte +0 -4
  55. package/src/PageNavigator.svelte +0 -94
  56. package/src/ResponsiveGrid.svelte +0 -73
  57. package/src/Scrollable.svelte +0 -8
  58. package/src/Searchable.svelte +0 -19
  59. package/src/Sidebar.svelte +0 -5
  60. package/src/Slider.svelte +0 -17
  61. package/src/SpinList.svelte +0 -48
  62. package/src/SplitPane.svelte +0 -109
  63. package/src/SplitView.svelte +0 -44
  64. package/src/Splitter.svelte +0 -95
  65. package/src/TabItem.svelte +0 -27
  66. package/src/TabItems.svelte +0 -34
  67. package/src/Tabs.svelte +0 -49
  68. package/src/Tree.svelte +0 -45
  69. package/src/actions/dismissable.js +0 -24
  70. package/src/actions/fillable.js +0 -114
  71. package/src/actions/hierarchy.js +0 -180
  72. package/src/actions/index.js +0 -7
  73. package/src/actions/navigable.js +0 -43
  74. package/src/actions/navigator.js +0 -179
  75. package/src/actions/pannable.js +0 -50
  76. package/src/actions/swipeable.js +0 -56
  77. package/src/actions/themeable.js +0 -23
  78. package/src/items/Collapsible.svelte +0 -51
  79. package/src/items/Connector.svelte +0 -26
  80. package/src/items/Link.svelte +0 -18
  81. package/src/items/Node.svelte +0 -52
  82. package/src/items/Pill.svelte +0 -33
  83. package/src/items/Separator.svelte +0 -1
  84. package/src/items/Summary.svelte +0 -27
  85. package/src/items/Text.svelte +0 -21
  86. package/src/items/index.js +0 -8
  87. package/src/list.js +0 -14
  88. package/src/mocks/Custom.svelte +0 -7
  89. package/src/mocks/index.js +0 -10
  90. package/src/stores/alerts.js +0 -3
  91. package/src/stores/index.js +0 -6
  92. package/src/stores/persist.js +0 -63
  93. package/src/stores/theme.js +0 -34
package/src/types.js ADDED
@@ -0,0 +1,160 @@
1
+ /**
2
+ * @typedef {'child' | 'last' | 'sibling' | 'empty' | 'icon'} LineType
3
+ */
4
+
5
+ /**
6
+ * @typedef {Object.<string, Function>} EventHandlers
7
+ * An object where keys are event names and values are event handler functions.
8
+ */
9
+
10
+ /**
11
+ * Component map to be used to render the item.
12
+ * @typedef {Object<string, import('svelte').SvelteComponent>} ComponentMap
13
+ */
14
+
15
+ /**
16
+ * Options for the sort order of the column.
17
+ *
18
+ * @typedef {'ascending'|'descending'|'none'} SortOptions
19
+ */
20
+
21
+ /**
22
+ * @typedef {'checked'|'unchecked'|'indeterminate'} SelectionState
23
+ */
24
+
25
+ /**
26
+ * Options for the horizontal alignment of the column content.
27
+ *
28
+ * @typedef {'left'|'middle'|'right'} HorizontalAlignOptions
29
+ */
30
+
31
+ /**
32
+ * Options for the action type of the column.
33
+ *
34
+ * @typedef {'select'|'edit'|'delete'} ActionTypes
35
+ */
36
+
37
+ /**
38
+ * Structure to map custom fields for rendering. This is used to identofy the attributes for various purposes.
39
+ *
40
+ * @typedef FieldMapping
41
+ * @property {string} [id='id'] Unique id for the item
42
+ * @property {string} [text='text'] the text to render
43
+ * @property {string} [value='value'] the value associated with the item
44
+ * @property {string} [url='url'] a URL
45
+ * @property {string} [icon='icon'] icon to render
46
+ * @property {string} [image='image'] the image to render
47
+ * @property {string} [children='children'] children of the item
48
+ * @property {string} [summary='summary'] summary of the item
49
+ * @property {string} [notes='notes'] notes for the item
50
+ * @property {string} [props='props'] additional properties
51
+ * @property {string} [isOpen='_open'] item is open or closed
52
+ * @property {string} [level='level'] level of item
53
+ * @property {string} [parent='parent'] item is a parent
54
+ * @property {string} [currency='currency] column specifying currency to be used for the current value
55
+ * @property {string} [isDeleted='_deleted'] item is deleted
56
+ * @property {FieldMapping} [fields] Field mapping to be used on children in the next level
57
+ */
58
+
59
+ /**
60
+ * Column metadata for the table.
61
+ *
62
+ * @typedef {Object} ColumnMetadata
63
+ *
64
+ * @property {string} name - The name of the column.
65
+ * @property {string} dataType - The data type of the column (e.g., "string", "number", "date").
66
+ * @property {FieldMapping} [fields] - Additional attributes for the column.
67
+ * @property {number} [digits=0] - The number of digits for numeric values (defaults to 0).
68
+ * @property {Function} formatter - A function to format the column value.
69
+ * @property {boolean} [virtual] - Indicates if the column is virtual (true/false).
70
+ * @property {boolean} [sortable] - Indicates if the column is sortable (true/false).
71
+ * @property {SortOptions} [sortOrder] - The sort order of the column.
72
+ * @property {HorizontalAlignOptions} [align] - The alignment of the column content.
73
+ * @property {ActionTypes} [action] - Action attribute for action columns.
74
+ */
75
+
76
+ /**
77
+ * Track the state of a row in the table.
78
+ *
79
+ * @typedef {Object} RowState
80
+ * @property {number} index - The index of the node in the flat list.
81
+ * @property {number} depth - The depth of the node in the hierarchy.
82
+ * @property {string} [value] - The value of the hierarchy node.
83
+ * @property {boolean} [isHidden] - Indicates whether the node is visible (true/false).
84
+ * @property {boolean} [isParent] - Indicates if this node is a parent (true/false).
85
+ * @property {boolean} [isExpanded] - Indicates whether the node is expanded (true/false).
86
+ * @property {number} [parentIndex] - The index of the parent node in the flat list.
87
+ * @property {SelectionState} [selected] - Indicates whether the node is selected (true/false/indeterminate).
88
+ * @property {Array<number>} childred - The indices of the children in the flat list.
89
+ */
90
+
91
+ /**
92
+ * Track the state of all rows in the table.
93
+ *
94
+ * @typedef {Object} RowStateMap
95
+ * @property {RowState[]} rows - Flat list of hierarchy nodes.
96
+ */
97
+
98
+ /**
99
+ * Shade mapping for color variables
100
+ *
101
+ * @typedef {Object} ShadeMapping
102
+ * @property {string} key - the variable name to be used
103
+ * @property {string} value - the value to be used
104
+ * @property {string} mode - light or dark mode
105
+ */
106
+
107
+ /**
108
+ * @typedef {Object} TickMark
109
+ * @property {number} value - The value of the tick mark.
110
+ * @property {string} label - The label for the tick mark.
111
+ * @property {boolean} major - Indicates if the tick mark is a major tick.
112
+ */
113
+
114
+ /**
115
+ * @typedef {Object} CalendarDay
116
+ * @property {number} day - The day of the month.
117
+ * @property {number} offset - indicates the offset for positioning
118
+ * @property {date} date - Datevalue for the day.
119
+ * @property {string} text - formatted text for the day.
120
+ * @property {boolean} holiday - Indicates if the day is a holiday.
121
+ * @property {boolean} weekend - Indicates if the day is on the weekend.
122
+ */
123
+
124
+ /**
125
+ * @typedef {Object} ColorPalette
126
+ * @property {string} 50 - The color for the 50 shade.
127
+ * @property {string} 100 - The color for the 100 shade.
128
+ * @property {string} 200 - The color for the 200 shade.
129
+ * @property {string} 300 - The color for the 300 shade.
130
+ * @property {string} 400 - The color for the 400 shade.
131
+ * @property {string} 500 - The color for the 500 shade.
132
+ * @property {string} 600 - The color for the 600 shade.
133
+ * @property {string} 700 - The color for the 700 shade.
134
+ * @property {string} 800 - The color for the 800 shade.
135
+ * @property {string} 900 - The color for the 900 shade.
136
+ * @property {string} 950 - The color for the 950 shade.
137
+ */
138
+
139
+ /**
140
+ * @typedef {Object<string,ColorPalette>} ColorCollection
141
+ */
142
+
143
+ /**
144
+ * @typedef {Object} ColorMapping
145
+ * @property {string} [primary] - The primary color.
146
+ * @property {string} [secondary] - The secondary color.
147
+ * @property {string} [tertiary] - The tertiary color.
148
+ * @property {string} [surface] - The surface color.
149
+ * @property {string} [info] - The info color.
150
+ * @property {string} [success] - The success color.
151
+ * @property {string} [warning] - The warning color.
152
+ * @property {string} [error] - The error color.
153
+ */
154
+
155
+ /**
156
+ * @typedef {Object} ColorTheme
157
+ * @property {ColorMapping} [mapping] - The color mapping.
158
+ * @property {ColorCollection} [colors] - The color collection.
159
+ */
160
+ export default {}
package/src/utils.js ADDED
@@ -0,0 +1,272 @@
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
+ * Checks dir/lang attributes of the html element for RTL
25
+ * @returns {'ltr' | 'rtl'}
26
+ */
27
+ function dirFromHtmlElement() {
28
+ const htmlDir = document.documentElement.getAttribute('dir')
29
+ if (htmlDir === 'rtl' || htmlDir === 'ltr') return htmlDir
30
+
31
+ const lang = document.documentElement.getAttribute('lang')
32
+ const primaryLang = lang ? lang.split('-')[0].toLowerCase() : ''
33
+ return RTL_LANGUAGES.includes(primaryLang) ? 'rtl' : 'ltr'
34
+ }
35
+
36
+ /**
37
+ * Detects text direction based on HTML lang attribute
38
+ * @returns {'ltr' | 'rtl'}
39
+ */
40
+ export function detectDirection() {
41
+ if (typeof document === 'undefined') return 'ltr'
42
+ return dirFromHtmlElement()
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
+ /**
185
+ * @param {unknown} value
186
+ * @returns {Function|null}
187
+ */
188
+ function asSnippet(value) {
189
+ return typeof value === 'function' ? value : null
190
+ }
191
+
192
+ export function resolveSnippet(snippets, proxy, fallback = ITEM_SNIPPET) {
193
+ const name = proxy && proxy.snippet
194
+ return asSnippet(name && snippets[name]) || asSnippet(snippets[fallback])
195
+ }
196
+
197
+ /**
198
+ * convert hex string to `{r} {g} {b}`
199
+ * @param {string} hex
200
+ * @return {string}
201
+ */
202
+ export function hex2rgb(hex) {
203
+ const [r, g, b] = hex.match(/\w\w/g).map((x) => parseInt(x, 16))
204
+ return `${r},${g},${b}`
205
+ }
206
+
207
+ /**
208
+ * Convert a CSS color value to r,g,b for use in CSS variables.
209
+ * Hex values (#rrggbb) are converted to "r,g,b" for rgba() support.
210
+ * All other CSS color formats (oklch, hsl, named) are returned as-is.
211
+ * Non-string values are returned unchanged.
212
+ * Note: non-hex values will NOT work with UnoCSS opacity utilities like bg-primary/50.
213
+ *
214
+ * @param {unknown} value
215
+ * @returns {unknown}
216
+ */
217
+ export function colorToRgb(value) {
218
+ if (typeof value === 'string' && /^#[0-9a-fA-F]{6}$/.test(value)) {
219
+ return hex2rgb(value)
220
+ }
221
+ return value
222
+ }
223
+
224
+ /**
225
+ * Checks if a string is a valid image URL
226
+ *
227
+ * @param {string} str - The string to check
228
+ * @returns {boolean} - Returns true if the string is an image URL
229
+ */
230
+ function isImageUrl(str) {
231
+ // Fallback regex-based validation
232
+ const fallbackValidation = () => {
233
+ const urlRegex = /^https?:\/\/.+\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff)(\?.*)?$/i
234
+ return urlRegex.test(str)
235
+ }
236
+
237
+ // Check if the string looks like a URL
238
+ try {
239
+ // Use browser-native URL constructor if available
240
+ if (typeof URL !== 'undefined') {
241
+ const url = new URL(str)
242
+ // Only accept HTTP/HTTPS protocols
243
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
244
+ return false
245
+ }
246
+ // Check common image extensions
247
+ const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.tiff']
248
+ const path = url.pathname.toLowerCase()
249
+ return imageExtensions.some((ext) => path.endsWith(ext))
250
+ }
251
+
252
+ // Fallback if URL constructor is not available
253
+ return fallbackValidation()
254
+ } catch {
255
+ // Fallback if URL constructor fails
256
+ return fallbackValidation()
257
+ }
258
+ }
259
+ /**
260
+ * A utility function that detects if a string is an image URL or image data (base64)
261
+ *
262
+ * @param {string} str - The string to check
263
+ * @returns {string|null} - Returns the original string if it's an image URL or image data, otherwise null
264
+ */
265
+ export function getImage(str) {
266
+ if (DATA_IMAGE_REGEX.test(str)) return str
267
+ // Check if it's a URL
268
+
269
+ if (isImageUrl(str)) return str
270
+
271
+ return null
272
+ }
@@ -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'
@@ -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}