@tokis/react 1.0.1 → 1.2.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 (84) hide show
  1. package/README.md +8 -6
  2. package/dist/__tests__/Accordion.test.d.ts +2 -0
  3. package/dist/__tests__/Accordion.test.d.ts.map +1 -0
  4. package/dist/__tests__/Accordion.test.js +144 -0
  5. package/dist/__tests__/Accordion.test.js.map +1 -0
  6. package/dist/__tests__/Button.test.d.ts +2 -0
  7. package/dist/__tests__/Button.test.d.ts.map +1 -0
  8. package/dist/__tests__/Button.test.js +104 -0
  9. package/dist/__tests__/Button.test.js.map +1 -0
  10. package/dist/__tests__/Checkbox.test.d.ts +2 -0
  11. package/dist/__tests__/Checkbox.test.d.ts.map +1 -0
  12. package/dist/__tests__/Checkbox.test.js +90 -0
  13. package/dist/__tests__/Checkbox.test.js.map +1 -0
  14. package/dist/__tests__/Select.test.d.ts +2 -0
  15. package/dist/__tests__/Select.test.d.ts.map +1 -0
  16. package/dist/__tests__/Select.test.js +119 -0
  17. package/dist/__tests__/Select.test.js.map +1 -0
  18. package/dist/__tests__/datagrid-utils.test.d.ts +2 -0
  19. package/dist/__tests__/datagrid-utils.test.d.ts.map +1 -0
  20. package/dist/__tests__/datagrid-utils.test.js +190 -0
  21. package/dist/__tests__/datagrid-utils.test.js.map +1 -0
  22. package/dist/__tests__/date-utils.test.d.ts +2 -0
  23. package/dist/__tests__/date-utils.test.d.ts.map +1 -0
  24. package/dist/__tests__/date-utils.test.js +180 -0
  25. package/dist/__tests__/date-utils.test.js.map +1 -0
  26. package/dist/cjs/components/accordion/index.js +1 -1
  27. package/dist/cjs/components/checkbox/index.js +2 -1
  28. package/dist/cjs/components/datagrid/index.js +161 -0
  29. package/dist/cjs/components/datagrid/types.js +2 -0
  30. package/dist/cjs/components/datagrid/utils.js +87 -0
  31. package/dist/cjs/components/datepicker/Calendar.js +117 -0
  32. package/dist/cjs/components/datepicker/date-utils.js +121 -0
  33. package/dist/cjs/components/datepicker/index.js +134 -0
  34. package/dist/cjs/components/extended/index.js +39 -31
  35. package/dist/cjs/components/layout/index.js +5 -4
  36. package/dist/cjs/components/treeview/index.js +1 -1
  37. package/dist/cjs/hooks/useId.js +18 -5
  38. package/dist/cjs/index.js +2 -0
  39. package/dist/components/accordion/index.js +1 -1
  40. package/dist/components/accordion/index.js.map +1 -1
  41. package/dist/components/checkbox/index.js +2 -1
  42. package/dist/components/checkbox/index.js.map +1 -1
  43. package/dist/components/datagrid/index.d.ts +20 -0
  44. package/dist/components/datagrid/index.d.ts.map +1 -0
  45. package/dist/components/datagrid/index.js +159 -0
  46. package/dist/components/datagrid/index.js.map +1 -0
  47. package/dist/components/datagrid/types.d.ts +92 -0
  48. package/dist/components/datagrid/types.d.ts.map +1 -0
  49. package/dist/components/datagrid/types.js +2 -0
  50. package/dist/components/datagrid/types.js.map +1 -0
  51. package/dist/components/datagrid/utils.d.ts +14 -0
  52. package/dist/components/datagrid/utils.d.ts.map +1 -0
  53. package/dist/components/datagrid/utils.js +80 -0
  54. package/dist/components/datagrid/utils.js.map +1 -0
  55. package/dist/components/datepicker/Calendar.d.ts +30 -0
  56. package/dist/components/datepicker/Calendar.d.ts.map +1 -0
  57. package/dist/components/datepicker/Calendar.js +115 -0
  58. package/dist/components/datepicker/Calendar.js.map +1 -0
  59. package/dist/components/datepicker/date-utils.d.ts +34 -0
  60. package/dist/components/datepicker/date-utils.d.ts.map +1 -0
  61. package/dist/components/datepicker/date-utils.js +107 -0
  62. package/dist/components/datepicker/date-utils.js.map +1 -0
  63. package/dist/components/datepicker/index.d.ts +52 -0
  64. package/dist/components/datepicker/index.d.ts.map +1 -0
  65. package/dist/components/datepicker/index.js +128 -0
  66. package/dist/components/datepicker/index.js.map +1 -0
  67. package/dist/components/extended/index.d.ts +14 -29
  68. package/dist/components/extended/index.d.ts.map +1 -1
  69. package/dist/components/extended/index.js +40 -27
  70. package/dist/components/extended/index.js.map +1 -1
  71. package/dist/components/layout/index.d.ts.map +1 -1
  72. package/dist/components/layout/index.js +5 -4
  73. package/dist/components/layout/index.js.map +1 -1
  74. package/dist/components/treeview/index.js +1 -1
  75. package/dist/components/treeview/index.js.map +1 -1
  76. package/dist/hooks/useId.d.ts +13 -3
  77. package/dist/hooks/useId.d.ts.map +1 -1
  78. package/dist/hooks/useId.js +19 -6
  79. package/dist/hooks/useId.js.map +1 -1
  80. package/dist/index.d.ts +2 -0
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +2 -0
  83. package/dist/index.js.map +1 -1
  84. package/package.json +7 -7
package/README.md CHANGED
@@ -1,20 +1,20 @@
1
- # /react
1
+ # @tokis/react
2
2
 
3
3
  React adapter for the Tokis design system — composable, accessible components, hooks, and theming context.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install /react /theme
8
+ npm install @tokis/react @tokis/theme @tokis/core @tokis/tokens
9
9
  ```
10
10
 
11
- > Or install everything at once: `npm install tokis`
11
+ > Or install everything at once: `npm install @tokis/tokis`
12
12
 
13
13
  ## Usage
14
14
 
15
15
  ```tsx
16
- import '/theme';
17
- import { ButtonRoot, ButtonLabel, ThemeProvider } from '/react';
16
+ import '@tokis/theme';
17
+ import { ButtonRoot, ButtonLabel, ThemeProvider } from '@tokis/react';
18
18
 
19
19
  function App() {
20
20
  return (
@@ -39,7 +39,9 @@ function App() {
39
39
 
40
40
  - `react` >= 18.0.0
41
41
  - `react-dom` >= 18.0.0
42
- - `/theme` ^0.1.0
42
+ - `@tokis/core` ^1.1.0
43
+ - `@tokis/tokens` ^1.1.0
44
+ - `@tokis/theme` ^1.1.0
43
45
 
44
46
  ## Documentation
45
47
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Accordion.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/Accordion.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,144 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { render, screen, fireEvent } from '@testing-library/react';
4
+ import { Accordion } from '../components/accordion/index.js';
5
+ // ─── Fixtures ──────────────────────────────────────────────────────────────
6
+ const items = [
7
+ { value: 'one', trigger: 'Section One', content: 'Content One' },
8
+ { value: 'two', trigger: 'Section Two', content: 'Content Two' },
9
+ { value: 'three', trigger: 'Section Three', content: 'Content Three', disabled: true },
10
+ ];
11
+ // ─── Rendering ─────────────────────────────────────────────────────────────
12
+ describe('Accordion rendering', () => {
13
+ it('renders all trigger buttons', () => {
14
+ render(_jsx(Accordion, { items: items }));
15
+ expect(screen.getByRole('button', { name: /Section One/ })).toBeInTheDocument();
16
+ expect(screen.getByRole('button', { name: /Section Two/ })).toBeInTheDocument();
17
+ expect(screen.getByRole('button', { name: /Section Three/ })).toBeInTheDocument();
18
+ });
19
+ it('renders content panels with role="region"', () => {
20
+ render(_jsx(Accordion, { items: items }));
21
+ // Panels are in the DOM but hidden from a11y tree when closed → use hidden:true
22
+ const regions = screen.getAllByRole('region', { hidden: true });
23
+ expect(regions).toHaveLength(3);
24
+ });
25
+ it('applies bordered variant class by default', () => {
26
+ const { container } = render(_jsx(Accordion, { items: items }));
27
+ expect(container.firstChild).toHaveClass('tokis-accordion-root');
28
+ expect(container.firstChild).not.toHaveClass('tokis-accordion-root--flush');
29
+ });
30
+ it('applies flush variant class when variant="flush"', () => {
31
+ const { container } = render(_jsx(Accordion, { items: items, variant: "flush" }));
32
+ expect(container.firstChild).toHaveClass('tokis-accordion-root--flush');
33
+ });
34
+ it('forwards className to the root element', () => {
35
+ const { container } = render(_jsx(Accordion, { items: items, className: "my-accordion" }));
36
+ expect(container.firstChild).toHaveClass('my-accordion');
37
+ });
38
+ });
39
+ // ─── Uncontrolled open/close ───────────────────────────────────────────────
40
+ describe('Accordion uncontrolled interactions', () => {
41
+ it('starts with all items closed by default', () => {
42
+ render(_jsx(Accordion, { items: items }));
43
+ const buttons = screen.getAllByRole('button');
44
+ buttons.forEach((btn) => {
45
+ if (!btn.hasAttribute('disabled')) {
46
+ expect(btn).toHaveAttribute('aria-expanded', 'false');
47
+ }
48
+ });
49
+ });
50
+ it('opens an item when its trigger is clicked', () => {
51
+ render(_jsx(Accordion, { items: items }));
52
+ const trigger = screen.getByRole('button', { name: /Section One/ });
53
+ fireEvent.click(trigger);
54
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
55
+ });
56
+ it('closes an open item when clicked again (collapsible=true)', () => {
57
+ render(_jsx(Accordion, { items: items }));
58
+ const trigger = screen.getByRole('button', { name: /Section One/ });
59
+ fireEvent.click(trigger); // open
60
+ fireEvent.click(trigger); // close
61
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
62
+ });
63
+ it('single mode: opening one item closes the previously open item', () => {
64
+ render(_jsx(Accordion, { items: items, type: "single" }));
65
+ const trigger1 = screen.getByRole('button', { name: /Section One/ });
66
+ const trigger2 = screen.getByRole('button', { name: /Section Two/ });
67
+ fireEvent.click(trigger1);
68
+ expect(trigger1).toHaveAttribute('aria-expanded', 'true');
69
+ fireEvent.click(trigger2);
70
+ expect(trigger2).toHaveAttribute('aria-expanded', 'true');
71
+ expect(trigger1).toHaveAttribute('aria-expanded', 'false');
72
+ });
73
+ it('multiple mode: multiple items can be open simultaneously', () => {
74
+ render(_jsx(Accordion, { items: items, type: "multiple" }));
75
+ const trigger1 = screen.getByRole('button', { name: /Section One/ });
76
+ const trigger2 = screen.getByRole('button', { name: /Section Two/ });
77
+ fireEvent.click(trigger1);
78
+ fireEvent.click(trigger2);
79
+ expect(trigger1).toHaveAttribute('aria-expanded', 'true');
80
+ expect(trigger2).toHaveAttribute('aria-expanded', 'true');
81
+ });
82
+ it('opens to defaultValue on mount', () => {
83
+ render(_jsx(Accordion, { items: items, defaultValue: "two" }));
84
+ const trigger2 = screen.getByRole('button', { name: /Section Two/ });
85
+ expect(trigger2).toHaveAttribute('aria-expanded', 'true');
86
+ });
87
+ });
88
+ // ─── Controlled mode ───────────────────────────────────────────────────────
89
+ describe('Accordion controlled', () => {
90
+ it('reflects the controlled value', () => {
91
+ render(_jsx(Accordion, { items: items, value: "one", onChange: vi.fn() }));
92
+ const trigger1 = screen.getByRole('button', { name: /Section One/ });
93
+ expect(trigger1).toHaveAttribute('aria-expanded', 'true');
94
+ });
95
+ it('calls onChange with the new value when a trigger is clicked', () => {
96
+ const onChange = vi.fn();
97
+ render(_jsx(Accordion, { items: items, value: "", onChange: onChange }));
98
+ fireEvent.click(screen.getByRole('button', { name: /Section One/ }));
99
+ expect(onChange).toHaveBeenCalledWith('one');
100
+ });
101
+ it('does not change state when controlled (parent manages state)', () => {
102
+ const onChange = vi.fn();
103
+ const { rerender } = render(_jsx(Accordion, { items: items, value: "one", onChange: onChange }));
104
+ fireEvent.click(screen.getByRole('button', { name: /Section Two/ }));
105
+ // State should still be 'one' since we didn't update the prop
106
+ const trigger1 = screen.getByRole('button', { name: /Section One/ });
107
+ expect(trigger1).toHaveAttribute('aria-expanded', 'true');
108
+ rerender(_jsx(Accordion, { items: items, value: "two", onChange: onChange }));
109
+ expect(screen.getByRole('button', { name: /Section Two/ })).toHaveAttribute('aria-expanded', 'true');
110
+ });
111
+ });
112
+ // ─── Disabled items ────────────────────────────────────────────────────────
113
+ describe('Accordion disabled items', () => {
114
+ it('renders disabled triggers as disabled', () => {
115
+ render(_jsx(Accordion, { items: items }));
116
+ const trigger3 = screen.getByRole('button', { name: /Section Three/ });
117
+ expect(trigger3).toBeDisabled();
118
+ });
119
+ it('does not open a disabled item when clicked', () => {
120
+ render(_jsx(Accordion, { items: items }));
121
+ const trigger3 = screen.getByRole('button', { name: /Section Three/ });
122
+ fireEvent.click(trigger3);
123
+ expect(trigger3).toHaveAttribute('aria-expanded', 'false');
124
+ });
125
+ });
126
+ // ─── ARIA relationships ────────────────────────────────────────────────────
127
+ describe('Accordion ARIA wiring', () => {
128
+ it('trigger aria-controls points to the panel id', () => {
129
+ render(_jsx(Accordion, { items: items.slice(0, 1) }));
130
+ const trigger = screen.getByRole('button', { name: /Section One/ });
131
+ const panelId = trigger.getAttribute('aria-controls');
132
+ expect(panelId).toBeTruthy();
133
+ const panel = document.getElementById(panelId);
134
+ expect(panel).toBeInTheDocument();
135
+ expect(panel).toHaveAttribute('role', 'region');
136
+ });
137
+ it('panel aria-labelledby points back to the trigger id', () => {
138
+ render(_jsx(Accordion, { items: items.slice(0, 1) }));
139
+ const trigger = screen.getByRole('button', { name: /Section One/ });
140
+ const panel = screen.getByRole('region', { hidden: true });
141
+ expect(panel).toHaveAttribute('aria-labelledby', trigger.id);
142
+ });
143
+ });
144
+ //# sourceMappingURL=Accordion.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.test.js","sourceRoot":"","sources":["../../src/__tests__/Accordion.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Button.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/Button.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { render, screen, fireEvent } from '@testing-library/react';
4
+ import { ButtonRoot } from '../components/button/ButtonRoot.js';
5
+ // ─── Rendering ─────────────────────────────────────────────────────────────
6
+ describe('ButtonRoot rendering', () => {
7
+ it('renders a <button> element by default', () => {
8
+ render(_jsx(ButtonRoot, { children: "Click me" }));
9
+ expect(screen.getByRole('button', { name: 'Click me' })).toBeInTheDocument();
10
+ });
11
+ it('renders children correctly', () => {
12
+ render(_jsx(ButtonRoot, { children: "Save Changes" }));
13
+ expect(screen.getByText('Save Changes')).toBeInTheDocument();
14
+ });
15
+ it('applies the primary variant class by default', () => {
16
+ render(_jsx(ButtonRoot, { children: "Button" }));
17
+ const btn = screen.getByRole('button');
18
+ expect(btn).toHaveClass('tokis-btn--primary');
19
+ });
20
+ it('applies the correct variant class for each variant', () => {
21
+ const variants = ['primary', 'secondary', 'ghost', 'outline', 'destructive', 'link'];
22
+ for (const variant of variants) {
23
+ const { unmount } = render(_jsx(ButtonRoot, { variant: variant, children: "Btn" }));
24
+ expect(screen.getByRole('button')).toHaveClass(`tokis-btn--${variant}`);
25
+ unmount();
26
+ }
27
+ });
28
+ it('applies size class for non-default sizes', () => {
29
+ render(_jsx(ButtonRoot, { size: "sm", children: "Sm" }));
30
+ expect(screen.getByRole('button')).toHaveClass('tokis-btn--sm');
31
+ });
32
+ it('does NOT apply a size class for the default md size', () => {
33
+ render(_jsx(ButtonRoot, { size: "md", children: "Md" }));
34
+ expect(screen.getByRole('button')).not.toHaveClass('tokis-btn--md');
35
+ });
36
+ it('applies tokis-btn--full when fullWidth=true', () => {
37
+ render(_jsx(ButtonRoot, { fullWidth: true, children: "Full" }));
38
+ expect(screen.getByRole('button')).toHaveClass('tokis-btn--full');
39
+ });
40
+ it('applies tokis-btn--icon-only when iconOnly=true', () => {
41
+ render(_jsx(ButtonRoot, { iconOnly: true, "aria-label": "Icon", children: "\u00D7" }));
42
+ expect(screen.getByRole('button')).toHaveClass('tokis-btn--icon-only');
43
+ });
44
+ it('renders a spinner and applies loading class when loading=true', () => {
45
+ render(_jsx(ButtonRoot, { loading: true, children: "Loading" }));
46
+ const btn = screen.getByRole('button');
47
+ expect(btn).toHaveClass('tokis-btn--loading');
48
+ expect(btn.querySelector('.tokis-spinner')).toBeInTheDocument();
49
+ });
50
+ it('forwards additional className', () => {
51
+ render(_jsx(ButtonRoot, { className: "my-custom-class", children: "Btn" }));
52
+ expect(screen.getByRole('button')).toHaveClass('my-custom-class');
53
+ });
54
+ it('passes through arbitrary HTML attributes (e.g., data-testid)', () => {
55
+ render(_jsx(ButtonRoot, { "data-testid": "save-btn", children: "Save" }));
56
+ expect(screen.getByTestId('save-btn')).toBeInTheDocument();
57
+ });
58
+ });
59
+ // ─── Disabled state ────────────────────────────────────────────────────────
60
+ describe('ButtonRoot disabled', () => {
61
+ it('sets the native disabled attribute when disabled=true', () => {
62
+ render(_jsx(ButtonRoot, { disabled: true, children: "Disabled" }));
63
+ expect(screen.getByRole('button')).toBeDisabled();
64
+ });
65
+ it('sets the native disabled attribute when loading=true (prevents interaction)', () => {
66
+ render(_jsx(ButtonRoot, { loading: true, children: "Loading" }));
67
+ expect(screen.getByRole('button')).toBeDisabled();
68
+ });
69
+ it('sets aria-busy when loading=true', () => {
70
+ render(_jsx(ButtonRoot, { loading: true, children: "Loading" }));
71
+ expect(screen.getByRole('button')).toHaveAttribute('aria-busy', 'true');
72
+ });
73
+ });
74
+ // ─── Click behaviour ───────────────────────────────────────────────────────
75
+ describe('ButtonRoot onClick', () => {
76
+ it('calls onClick handler when clicked', () => {
77
+ const onClick = vi.fn();
78
+ render(_jsx(ButtonRoot, { onClick: onClick, children: "Go" }));
79
+ fireEvent.click(screen.getByRole('button'));
80
+ expect(onClick).toHaveBeenCalledTimes(1);
81
+ });
82
+ it('does NOT call onClick when disabled', () => {
83
+ const onClick = vi.fn();
84
+ render(_jsx(ButtonRoot, { disabled: true, onClick: onClick, children: "Go" }));
85
+ fireEvent.click(screen.getByRole('button'));
86
+ expect(onClick).not.toHaveBeenCalled();
87
+ });
88
+ it('does NOT call onClick when loading', () => {
89
+ const onClick = vi.fn();
90
+ render(_jsx(ButtonRoot, { loading: true, onClick: onClick, children: "Go" }));
91
+ fireEvent.click(screen.getByRole('button'));
92
+ expect(onClick).not.toHaveBeenCalled();
93
+ });
94
+ });
95
+ // ─── Polymorphic rendering ─────────────────────────────────────────────────
96
+ describe('ButtonRoot as prop (polymorphic)', () => {
97
+ it('renders as <a> when as="a"', () => {
98
+ render(_jsx(ButtonRoot, { as: "a", href: "/home", children: "Home" }));
99
+ const link = screen.getByRole('link', { name: 'Home' });
100
+ expect(link).toBeInTheDocument();
101
+ expect(link.tagName).toBe('A');
102
+ });
103
+ });
104
+ //# sourceMappingURL=Button.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.test.js","sourceRoot":"","sources":["../../src/__tests__/Button.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Checkbox.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/Checkbox.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,90 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { render, screen, fireEvent } from '@testing-library/react';
4
+ import { Checkbox } from '../components/checkbox/index.js';
5
+ // ─── Rendering ─────────────────────────────────────────────────────────────
6
+ describe('Checkbox rendering', () => {
7
+ it('renders an accessible checkbox input', () => {
8
+ render(_jsx(Checkbox, { label: "Accept terms" }));
9
+ expect(screen.getByRole('checkbox', { name: 'Accept terms' })).toBeInTheDocument();
10
+ });
11
+ it('renders with aria-label when no label prop is given', () => {
12
+ render(_jsx(Checkbox, { "aria-label": "Toggle feature" }));
13
+ expect(screen.getByRole('checkbox', { name: 'Toggle feature' })).toBeInTheDocument();
14
+ });
15
+ it('renders description text when provided', () => {
16
+ render(_jsx(Checkbox, { label: "Subscribe", description: "Get weekly newsletter" }));
17
+ expect(screen.getByText('Get weekly newsletter')).toBeInTheDocument();
18
+ });
19
+ it('associates description via aria-describedby', () => {
20
+ render(_jsx(Checkbox, { label: "Subscribe", description: "Get weekly newsletter" }));
21
+ const checkbox = screen.getByRole('checkbox');
22
+ const descId = checkbox.getAttribute('aria-describedby');
23
+ expect(descId).toBeTruthy();
24
+ expect(document.getElementById(descId)).toHaveTextContent('Get weekly newsletter');
25
+ });
26
+ it('forwards id to the input element', () => {
27
+ render(_jsx(Checkbox, { label: "Check", id: "my-checkbox" }));
28
+ expect(document.getElementById('my-checkbox')).toBeInTheDocument();
29
+ expect(document.getElementById('my-checkbox')).toHaveAttribute('type', 'checkbox');
30
+ });
31
+ it('forwards name and value attributes', () => {
32
+ render(_jsx(Checkbox, { label: "Option A", name: "options", value: "a" }));
33
+ const checkbox = screen.getByRole('checkbox');
34
+ expect(checkbox).toHaveAttribute('name', 'options');
35
+ expect(checkbox).toHaveAttribute('value', 'a');
36
+ });
37
+ });
38
+ // ─── Checked state ─────────────────────────────────────────────────────────
39
+ describe('Checkbox checked state', () => {
40
+ it('is unchecked by default', () => {
41
+ render(_jsx(Checkbox, { label: "Option" }));
42
+ expect(screen.getByRole('checkbox')).not.toBeChecked();
43
+ });
44
+ it('reflects controlled checked=true', () => {
45
+ render(_jsx(Checkbox, { label: "Option", checked: true, onChange: vi.fn() }));
46
+ expect(screen.getByRole('checkbox')).toBeChecked();
47
+ });
48
+ it('reflects controlled checked=false', () => {
49
+ render(_jsx(Checkbox, { label: "Option", checked: false, onChange: vi.fn() }));
50
+ expect(screen.getByRole('checkbox')).not.toBeChecked();
51
+ });
52
+ it('starts checked when defaultChecked=true (uncontrolled)', () => {
53
+ render(_jsx(Checkbox, { label: "Option", defaultChecked: true }));
54
+ expect(screen.getByRole('checkbox')).toBeChecked();
55
+ });
56
+ });
57
+ // ─── onChange callback ─────────────────────────────────────────────────────
58
+ describe('Checkbox onChange', () => {
59
+ it('calls onChange(true) when unchecked checkbox is clicked', () => {
60
+ const onChange = vi.fn();
61
+ render(_jsx(Checkbox, { label: "Option", checked: false, onChange: onChange }));
62
+ fireEvent.click(screen.getByRole('checkbox'));
63
+ expect(onChange).toHaveBeenCalledWith(true);
64
+ });
65
+ it('calls onChange(false) when checked checkbox is clicked', () => {
66
+ const onChange = vi.fn();
67
+ render(_jsx(Checkbox, { label: "Option", checked: true, onChange: onChange }));
68
+ fireEvent.click(screen.getByRole('checkbox'));
69
+ expect(onChange).toHaveBeenCalledWith(false);
70
+ });
71
+ it('does NOT call onChange when disabled', () => {
72
+ const onChange = vi.fn();
73
+ render(_jsx(Checkbox, { label: "Option", disabled: true, onChange: onChange }));
74
+ fireEvent.click(screen.getByRole('checkbox'));
75
+ expect(onChange).not.toHaveBeenCalled();
76
+ });
77
+ });
78
+ // ─── Disabled state ────────────────────────────────────────────────────────
79
+ describe('Checkbox disabled', () => {
80
+ it('renders as disabled when disabled=true', () => {
81
+ render(_jsx(Checkbox, { label: "Option", disabled: true }));
82
+ expect(screen.getByRole('checkbox')).toBeDisabled();
83
+ });
84
+ it('adds data-disabled to the root label', () => {
85
+ render(_jsx(Checkbox, { label: "Option", disabled: true }));
86
+ const root = screen.getByRole('checkbox').closest('.tokis-checkbox-root');
87
+ expect(root).toHaveAttribute('data-disabled');
88
+ });
89
+ });
90
+ //# sourceMappingURL=Checkbox.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.test.js","sourceRoot":"","sources":["../../src/__tests__/Checkbox.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Select.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/Select.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi } from 'vitest';
3
+ import { render, screen, fireEvent } from '@testing-library/react';
4
+ import { Select } from '../components/select/index.js';
5
+ // ─── Fixtures ──────────────────────────────────────────────────────────────
6
+ const options = [
7
+ { value: 'apple', label: 'Apple' },
8
+ { value: 'banana', label: 'Banana' },
9
+ { value: 'cherry', label: 'Cherry', disabled: true },
10
+ { value: 'date', label: 'Date' },
11
+ ];
12
+ // ─── Rendering ─────────────────────────────────────────────────────────────
13
+ describe('Select rendering', () => {
14
+ it('renders a combobox trigger button', () => {
15
+ render(_jsx(Select, { options: options }));
16
+ expect(screen.getByRole('combobox')).toBeInTheDocument();
17
+ });
18
+ it('shows placeholder text when no value is selected', () => {
19
+ render(_jsx(Select, { options: options, placeholder: "Pick a fruit" }));
20
+ expect(screen.getByText('Pick a fruit')).toBeInTheDocument();
21
+ });
22
+ it('renders the label when provided', () => {
23
+ render(_jsx(Select, { options: options, label: "Favourite Fruit" }));
24
+ expect(screen.getByText('Favourite Fruit')).toBeInTheDocument();
25
+ });
26
+ it('renders helper text when provided', () => {
27
+ render(_jsx(Select, { options: options, helperText: "Select one option" }));
28
+ expect(screen.getByText('Select one option')).toBeInTheDocument();
29
+ });
30
+ it('shows selected option label for a controlled value', () => {
31
+ render(_jsx(Select, { options: options, value: "banana", onChange: vi.fn() }));
32
+ expect(screen.getByRole('combobox')).toHaveTextContent('Banana');
33
+ });
34
+ });
35
+ // ─── Dropdown open/close ───────────────────────────────────────────────────
36
+ describe('Select dropdown open/close', () => {
37
+ it('opens the dropdown when the trigger is clicked', () => {
38
+ render(_jsx(Select, { options: options }));
39
+ fireEvent.click(screen.getByRole('combobox'));
40
+ // All enabled options should be visible in the listbox
41
+ expect(screen.getByRole('listbox')).toBeInTheDocument();
42
+ expect(screen.getByRole('option', { name: 'Apple' })).toBeInTheDocument();
43
+ expect(screen.getByRole('option', { name: 'Banana' })).toBeInTheDocument();
44
+ });
45
+ it('closes the dropdown after selecting an option', () => {
46
+ render(_jsx(Select, { options: options }));
47
+ fireEvent.click(screen.getByRole('combobox'));
48
+ fireEvent.click(screen.getByRole('option', { name: 'Apple' }));
49
+ expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
50
+ });
51
+ it('closes on Escape key', () => {
52
+ render(_jsx(Select, { options: options }));
53
+ fireEvent.click(screen.getByRole('combobox'));
54
+ expect(screen.getByRole('listbox')).toBeInTheDocument();
55
+ fireEvent.keyDown(screen.getByRole('combobox'), { key: 'Escape' });
56
+ expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
57
+ });
58
+ it('sets aria-expanded=true when open', () => {
59
+ render(_jsx(Select, { options: options }));
60
+ const trigger = screen.getByRole('combobox');
61
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
62
+ fireEvent.click(trigger);
63
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
64
+ });
65
+ });
66
+ // ─── Selection ─────────────────────────────────────────────────────────────
67
+ describe('Select selection', () => {
68
+ it('calls onChange with the selected value', () => {
69
+ const onChange = vi.fn();
70
+ render(_jsx(Select, { options: options, onChange: onChange }));
71
+ fireEvent.click(screen.getByRole('combobox'));
72
+ fireEvent.click(screen.getByRole('option', { name: 'Banana' }));
73
+ expect(onChange).toHaveBeenCalledWith('banana');
74
+ });
75
+ it('updates displayed value in uncontrolled mode after selection', () => {
76
+ render(_jsx(Select, { options: options }));
77
+ fireEvent.click(screen.getByRole('combobox'));
78
+ fireEvent.click(screen.getByRole('option', { name: 'Date' }));
79
+ expect(screen.getByRole('combobox')).toHaveTextContent('Date');
80
+ });
81
+ it('shows selected state via defaultValue on mount', () => {
82
+ render(_jsx(Select, { options: options, defaultValue: "banana" }));
83
+ expect(screen.getByRole('combobox')).toHaveTextContent('Banana');
84
+ });
85
+ it('does not call onChange for disabled options', () => {
86
+ const onChange = vi.fn();
87
+ render(_jsx(Select, { options: options, onChange: onChange }));
88
+ fireEvent.click(screen.getByRole('combobox'));
89
+ const cherryOption = screen.getByRole('option', { name: 'Cherry' });
90
+ fireEvent.click(cherryOption);
91
+ expect(onChange).not.toHaveBeenCalled();
92
+ });
93
+ });
94
+ // ─── Disabled state ────────────────────────────────────────────────────────
95
+ describe('Select disabled', () => {
96
+ it('renders the trigger as disabled when disabled=true', () => {
97
+ render(_jsx(Select, { options: options, disabled: true }));
98
+ expect(screen.getByRole('combobox')).toBeDisabled();
99
+ });
100
+ it('does not open the dropdown when disabled', () => {
101
+ render(_jsx(Select, { options: options, disabled: true }));
102
+ fireEvent.click(screen.getByRole('combobox'));
103
+ expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
104
+ });
105
+ });
106
+ // ─── Keyboard navigation ───────────────────────────────────────────────────
107
+ describe('Select keyboard navigation', () => {
108
+ it('opens the dropdown on ArrowDown', () => {
109
+ render(_jsx(Select, { options: options }));
110
+ fireEvent.keyDown(screen.getByRole('combobox'), { key: 'ArrowDown' });
111
+ expect(screen.getByRole('listbox')).toBeInTheDocument();
112
+ });
113
+ it('opens the dropdown on Enter', () => {
114
+ render(_jsx(Select, { options: options }));
115
+ fireEvent.keyDown(screen.getByRole('combobox'), { key: 'Enter' });
116
+ expect(screen.getByRole('listbox')).toBeInTheDocument();
117
+ });
118
+ });
119
+ //# sourceMappingURL=Select.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.test.js","sourceRoot":"","sources":["../../src/__tests__/Select.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=datagrid-utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datagrid-utils.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/datagrid-utils.test.ts"],"names":[],"mappings":""}