@rokkit/ui 1.0.5 → 1.1.0

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 (59) hide show
  1. package/package.json +7 -6
  2. package/src/MarkdownRenderer.svelte +13 -1
  3. package/src/components/AlertList.svelte +1 -13
  4. package/src/components/Avatar.svelte +1 -18
  5. package/src/components/Badge.svelte +1 -16
  6. package/src/components/BreadCrumbs.svelte +2 -21
  7. package/src/components/Card.svelte +1 -18
  8. package/src/components/Carousel.svelte +2 -27
  9. package/src/components/CodeBlock.svelte +130 -0
  10. package/src/components/CodeGroup.svelte +408 -0
  11. package/src/components/Connector.svelte +2 -8
  12. package/src/components/Divider.svelte +1 -8
  13. package/src/components/Frame.svelte +30 -0
  14. package/src/components/ItemContent.svelte +4 -2
  15. package/src/components/Message.svelte +1 -22
  16. package/src/components/NavContent.svelte +1 -16
  17. package/src/components/Pill.svelte +1 -24
  18. package/src/components/ProgressBar.svelte +1 -8
  19. package/src/components/Rating.svelte +2 -22
  20. package/src/components/ResponsiveGrid.svelte +1 -14
  21. package/src/components/Reveal.svelte +1 -23
  22. package/src/components/Select.svelte +90 -9
  23. package/src/components/Shine.svelte +1 -19
  24. package/src/components/Stack.svelte +1 -16
  25. package/src/components/StatusList.svelte +3 -2
  26. package/src/components/Stepper.svelte +2 -41
  27. package/src/components/Tilt.svelte +1 -13
  28. package/src/components/Toggle.svelte +83 -33
  29. package/src/components/index.ts +3 -0
  30. package/src/index.ts +4 -0
  31. package/src/types/alert-list.ts +28 -0
  32. package/src/types/avatar.ts +41 -0
  33. package/src/types/badge.ts +37 -0
  34. package/src/types/breadcrumbs.ts +43 -0
  35. package/src/types/card.ts +38 -0
  36. package/src/types/carousel.ts +49 -0
  37. package/src/types/code.ts +102 -1
  38. package/src/types/connector.ts +22 -0
  39. package/src/types/divider.ts +20 -0
  40. package/src/types/frame.ts +29 -0
  41. package/src/types/index.ts +66 -0
  42. package/src/types/item-content.ts +26 -0
  43. package/src/types/message.ts +54 -0
  44. package/src/types/nav-content.ts +31 -0
  45. package/src/types/pill.ts +43 -0
  46. package/src/types/progress-bar.ts +19 -0
  47. package/src/types/rating.ts +43 -0
  48. package/src/types/responsive-grid.ts +25 -0
  49. package/src/types/reveal.ts +49 -0
  50. package/src/types/shine.ts +37 -0
  51. package/src/types/stack.ts +40 -0
  52. package/src/types/status-list.ts +42 -0
  53. package/src/types/stepper.ts +74 -0
  54. package/src/types/tilt.ts +28 -0
  55. package/src/types/toggle.ts +12 -0
  56. package/src/types/tree.ts +46 -4
  57. package/src/utils/palette.ts +4 -2
  58. package/src/utils/shiki.ts +22 -1
  59. package/src/utils/upload.js +8 -8
@@ -0,0 +1,42 @@
1
+ /**
2
+ * StatusList Component Types
3
+ *
4
+ * Renders a vertical list of status rows — each with a label and a status
5
+ * keyword that maps to a badge icon (e.g. `pass`, `fail`, `warn`).
6
+ */
7
+
8
+ import { DEFAULT_STATE_ICONS } from '@rokkit/core'
9
+
10
+ /**
11
+ * Built-in badge status keys provided by `@rokkit/core`. Consumers may also
12
+ * pass any other string and supply a matching entry via the `icons` prop.
13
+ */
14
+ export type StatusListStatus = keyof typeof DEFAULT_STATE_ICONS.badge | (string & {})
15
+
16
+ /**
17
+ * One row in a StatusList — a label paired with a status keyword.
18
+ */
19
+ export interface StatusListItem {
20
+ /** Text rendered for this row. */
21
+ text: string
22
+
23
+ /** Status keyword used to look up the badge icon. */
24
+ status: StatusListStatus
25
+ }
26
+
27
+ /**
28
+ * Props for the StatusList component.
29
+ */
30
+ export interface StatusListProps {
31
+ /** Additional CSS class applied to the root element. */
32
+ class?: string
33
+
34
+ /** Rows to render. */
35
+ items: StatusListItem[]
36
+
37
+ /**
38
+ * Override the default badge icon map (`pass` / `fail` / `warn` / `unknown`).
39
+ * Merged on top of `DEFAULT_STATE_ICONS.badge` from `@rokkit/core`.
40
+ */
41
+ icons?: Partial<Record<string, string>>
42
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Stepper Component Types
3
+ */
4
+
5
+ import type { Snippet } from 'svelte'
6
+
7
+ /** Layout orientation for the stepper. */
8
+ export type StepperOrientation = 'horizontal' | 'vertical'
9
+
10
+ /**
11
+ * Definition for a single step in the stepper.
12
+ */
13
+ export interface StepperStep {
14
+ /** Step label (shown below the circle). */
15
+ text: string
16
+
17
+ /** Short text shown inside the circle. Default: step number. */
18
+ label?: string
19
+
20
+ /** Step is finished — shows the check icon. */
21
+ completed?: boolean
22
+
23
+ /** Step cannot be navigated to. */
24
+ disabled?: boolean
25
+
26
+ /** Number of sub-stages within this step. Default `1`. */
27
+ stages?: number
28
+ }
29
+
30
+ /**
31
+ * Icon overrides for the Stepper component.
32
+ */
33
+ export interface StepperIcons {
34
+ /** Icon class for the check / completed state. */
35
+ check?: string
36
+ }
37
+
38
+ /**
39
+ * Props for the Stepper component.
40
+ */
41
+ export interface StepperProps {
42
+ /** Array of step definitions. */
43
+ steps?: StepperStep[]
44
+
45
+ /** Current step index (bindable). */
46
+ current?: number
47
+
48
+ /** Current sub-stage within the step (bindable, 0-based). */
49
+ currentStage?: number
50
+
51
+ /**
52
+ * In linear mode only completed steps + the first incomplete step
53
+ * are clickable.
54
+ */
55
+ linear?: boolean
56
+
57
+ /** Layout orientation. */
58
+ orientation?: StepperOrientation
59
+
60
+ /** Accessible label for the surrounding group. */
61
+ label?: string
62
+
63
+ /** Custom icon overrides. */
64
+ icons?: StepperIcons
65
+
66
+ /** Called when a step (or sub-stage dot) is clicked. */
67
+ onclick?: (step: number, stage?: number) => void
68
+
69
+ /** Content snippet rendered below the stepper. */
70
+ content?: Snippet<[StepperStep, number]>
71
+
72
+ /** Additional CSS class. */
73
+ class?: string
74
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tilt Component Types
3
+ */
4
+
5
+ import type { Snippet } from 'svelte'
6
+
7
+ /**
8
+ * Props for the Tilt component.
9
+ *
10
+ * Wraps content in a container that rotates in response to pointer
11
+ * movement, with optional brightness modulation.
12
+ */
13
+ export interface TiltProps {
14
+ /** Maximum rotation angle in degrees. Default `10`. */
15
+ maxRotation?: number
16
+
17
+ /** Whether to adjust brightness based on pointer Y position. */
18
+ setBrightness?: boolean
19
+
20
+ /** CSS perspective value in pixels. Default `600`. */
21
+ perspective?: number
22
+
23
+ /** Additional CSS class. */
24
+ class?: string
25
+
26
+ /** Content to tilt. */
27
+ children?: Snippet
28
+ }
@@ -32,10 +32,22 @@ export type ToggleItemSnippet = Snippet<[ProxyItem, boolean]>
32
32
  // Component Props Types
33
33
  // =============================================================================
34
34
 
35
+ /**
36
+ * Visual variant of the Toggle.
37
+ * - `'group'` (default) — segmented radio-group rendering, one button per option.
38
+ * - `'button'` — single button that cycles through the options on each click.
39
+ * The rendered content represents the *next* option (the one you'd switch to),
40
+ * so users can read the click destination at a glance.
41
+ */
42
+ export type ToggleVariant = 'group' | 'button'
43
+
35
44
  /**
36
45
  * Props for the Toggle component
37
46
  */
38
47
  export interface ToggleProps {
48
+ /** Visual variant. Default: 'group'. */
49
+ variant?: ToggleVariant
50
+
39
51
  /** Array of toggle options (strings, numbers, or objects) */
40
52
  options?: ToggleItem[]
41
53
 
package/src/types/tree.ts CHANGED
@@ -14,17 +14,59 @@ import { DEFAULT_STATE_ICONS } from '@rokkit/core'
14
14
  // =============================================================================
15
15
 
16
16
  /**
17
- * Field mapping configuration for tree data.
18
- * Extends base field mapping with tree-specific fields.
17
+ * Field mapping configuration for tree data — what the consumer passes
18
+ * to the Tree component. Both `expanded` and `level` are optional here
19
+ * because Tree falls back to `defaultTreeFields` for any field the
20
+ * consumer omits.
21
+ *
22
+ * Inside Tree the fields are merged with `defaultTreeFields` to produce
23
+ * a `ResolvedTreeFields` value where every key is guaranteed present.
24
+ * Downstream code that needs string field names without null-guards
25
+ * should use `ResolvedTreeFields` rather than `TreeFields`.
19
26
  */
20
27
  export interface TreeFields extends Record<string, string> {
21
- /** Field for expanded state - default: 'expanded' */
28
+ /**
29
+ * Name of the field on each tree item that holds its expanded state.
30
+ * The value at that field is expected to be a `boolean`.
31
+ *
32
+ * Optional — falls back to the default field name `'expanded'`. After
33
+ * `resolveTreeFields` is applied the resolved key is guaranteed present
34
+ * (see {@link ResolvedTreeFields}).
35
+ */
22
36
  expanded?: string
23
37
 
24
- /** Field for node level/depth - default: 'level' */
38
+ /**
39
+ * Name of the field on each tree item that holds its depth in the tree.
40
+ * The value at that field is expected to be a `number`.
41
+ *
42
+ * Optional — falls back to the default field name `'level'`. After
43
+ * `resolveTreeFields` is applied the resolved key is guaranteed present
44
+ * (see {@link ResolvedTreeFields}).
45
+ */
25
46
  level?: string
26
47
  }
27
48
 
49
+ /**
50
+ * Tree fields after defaults have been applied — every field name is a
51
+ * non-null string. Use this type for any function or store that needs
52
+ * to read a field name without re-applying defaults.
53
+ *
54
+ * Construct from a `TreeFields` via `resolveTreeFields(fields)` (or by
55
+ * spreading `defaultTreeFields` first, e.g.
56
+ * `{ ...defaultTreeFields, ...userFields }`).
57
+ */
58
+ export type ResolvedTreeFields = Required<TreeFields>
59
+
60
+ /**
61
+ * Merge consumer-provided field overrides with the default field
62
+ * mapping so every key resolves to a string. Tree calls this once on
63
+ * its `fields` prop before passing the result to ProxyTree / line
64
+ * builders.
65
+ */
66
+ export function resolveTreeFields(fields: TreeFields = {}): ResolvedTreeFields {
67
+ return { ...defaultTreeFields, ...fields }
68
+ }
69
+
28
70
  /**
29
71
  * Default field mapping values for tree
30
72
  */
@@ -719,16 +719,18 @@ export function resetPalette(
719
719
  }
720
720
 
721
721
  /**
722
- * Save palette to localStorage
722
+ * Save palette to localStorage. SSR-safe.
723
723
  */
724
724
  export function savePalette(key: string, mapping: Partial<Record<ColorRole, string>>): void {
725
+ if (typeof localStorage === 'undefined') return
725
726
  localStorage.setItem(key, JSON.stringify(mapping))
726
727
  }
727
728
 
728
729
  /**
729
- * Load palette from localStorage
730
+ * Load palette from localStorage. SSR-safe.
730
731
  */
731
732
  export function loadPalette(key: string): Partial<Record<ColorRole, string>> | null {
733
+ if (typeof localStorage === 'undefined') return null
732
734
  const stored = localStorage.getItem(key)
733
735
  if (stored) {
734
736
  try {
@@ -76,6 +76,27 @@ function resolveTheme(themeOption: string | undefined): BundledTheme {
76
76
  return themeOption as BundledTheme
77
77
  }
78
78
 
79
+ /**
80
+ * Map fence languages (used by @rokkit/blocks plugins) to a Shiki-known
81
+ * grammar. The fence is *semantic* (the renderer routes by language name),
82
+ * but the body is plain JSON — highlight it as such instead of falling
83
+ * back to unstyled text.
84
+ */
85
+ const LANGUAGE_ALIASES: Record<string, BundledLanguage> = {
86
+ plot: 'json',
87
+ table: 'json',
88
+ form: 'json',
89
+ list: 'json',
90
+ stepper: 'json',
91
+ sparkline: 'json',
92
+ chart: 'json'
93
+ }
94
+
95
+ function resolveLang(input: string | undefined): BundledLanguage {
96
+ if (!input) return 'text' as BundledLanguage
97
+ return (LANGUAGE_ALIASES[input] ?? input) as BundledLanguage
98
+ }
99
+
79
100
  function isValidCode(code: unknown): code is string {
80
101
  return Boolean(code) && typeof code === 'string'
81
102
  }
@@ -84,7 +105,7 @@ export async function highlightCode(code: string, options: HighlightOptions = {}
84
105
  if (!isValidCode(code)) throw new Error('Invalid code provided for highlighting')
85
106
 
86
107
  const hl = await initializeHighlighter()
87
- const lang = (options.lang ?? 'text') as BundledLanguage
108
+ const lang = resolveLang(options.lang as string | undefined)
88
109
  const theme = resolveTheme(options.theme)
89
110
  const loadedLangs = hl.getLoadedLanguages()
90
111
  const effectiveLang = loadedLangs.includes(lang) ? lang : 'text'
@@ -61,11 +61,11 @@ export function validateFile(file, { accept, maxSize } = {}) {
61
61
  * @returns {string}
62
62
  */
63
63
  const MIME_PREFIX_ICONS = [
64
- ['image/', 'i-lucide:image'],
65
- ['video/', 'i-lucide:video'],
66
- ['audio/', 'i-lucide:music'],
67
- ['text/', 'i-lucide:file-text'],
68
- ['application/pdf', 'i-lucide:file-text']
64
+ ['image/', 'media-image'],
65
+ ['video/', 'media-video'],
66
+ ['audio/', 'media-audio'],
67
+ ['text/', 'doc-text'],
68
+ ['application/pdf', 'doc-pdf']
69
69
  ]
70
70
 
71
71
  function getPrefixIcon(mimeType) {
@@ -76,11 +76,11 @@ function getPrefixIcon(mimeType) {
76
76
  }
77
77
 
78
78
  export function inferIcon(mimeType) {
79
- if (!mimeType) return 'i-lucide:file'
79
+ if (!mimeType) return 'doc-default'
80
80
  const prefixIcon = getPrefixIcon(mimeType)
81
81
  if (prefixIcon) return prefixIcon
82
- if (ARCHIVE_TYPES.has(mimeType)) return 'i-lucide:archive'
83
- return 'i-lucide:file'
82
+ if (ARCHIVE_TYPES.has(mimeType)) return 'doc-archive'
83
+ return 'doc-default'
84
84
  }
85
85
 
86
86
  /**