addon-ui 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # Addon UI (addon-ui)
1
+ # addon-ui
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/addon-ui.svg)](https://www.npmjs.com/package/addon-ui)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/addon-ui.svg)](https://www.npmjs.com/package/addon-ui)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- A comprehensive UI component library designed for the Addon Bone framework.
7
+ Addon UI - A comprehensive UI component library designed for the Addon Bone framework.
8
8
  This library provides a set of customizable React components with theming capabilities to build modern,
9
9
  responsive user interfaces.
10
10
 
@@ -19,55 +19,72 @@ responsive user interfaces.
19
19
  ## Table of Contents
20
20
 
21
21
  - [Installation](#installation)
22
+ - [Components](#components)
22
23
  - [Basic Usage](#basic-usage)
23
24
  - [Integration](#integration)
24
25
  - [Customization](#customization)
25
26
  - [Using Extra Props](#using-extra-props)
26
- - [Component Examples](#component-examples)
27
- - [Supported Components](#supported-components)
28
- - [Avatar](#avatar)
29
- - [BaseButton](#basebutton)
30
- - [Button](#button)
31
- - [Checkbox](#checkbox)
32
- - [Dialog](#dialog)
33
- - [Drawer](#drawer)
34
- - [Footer](#footer)
35
- - [Header](#header)
36
- - [Highlight](#highlight)
37
- - [Icon](#icon)
38
- - [IconButton](#iconbutton)
39
- - [Layout](#layout)
40
- - [List](#list)
41
- - [ListItem](#listitem)
42
- - [Modal](#modal)
43
- - [Odometer](#odometer)
44
- - [ScrollArea](#scrollarea)
45
- - [SvgSprite](#svgsprite)
46
- - [Switch](#switch)
47
- - [Tag](#tag)
48
- - [TextArea](#textarea)
49
- - [TextField](#textfield)
50
- - [Toast](#toast)
51
- - [Tooltip](#tooltip)
52
- - [View](#view)
53
- - [ViewDrawer](#viewdrawer)
54
- - [ViewModal](#viewmodal)
55
- - [License](#license)
27
+ - [Theming and style reuse](#theming-and-style-reuse)
28
+ - [Radix UI and third-party integrations](#radix-ui-and-third-party-integrations)
29
+ - [Icons and sprite](#icons-and-sprite)
30
+ - [Extra props](#extra-props-cross-cutting-configuration)
31
+ - [Contributing](#contributing)
56
32
 
57
33
  ## Installation
58
34
 
59
- Using npm:
35
+ ### npm:
60
36
 
61
37
  ```bash
62
38
  npm install addon-ui
63
39
  ```
64
40
 
65
- Using Yarn:
41
+ ### pnpm:
42
+
43
+ ```bash
44
+ pnpm add addon-ui
45
+ ```
46
+
47
+ ### yarn:
66
48
 
67
49
  ```bash
68
50
  yarn add addon-ui
69
51
  ```
70
52
 
53
+ ## Components
54
+
55
+ This library now ships with dedicated documentation files for each component in the docs/ directory. Start here:
56
+
57
+ - [Avatar](docs/Avatar.md)
58
+ - [Button](docs/Button.md)
59
+ - [Checkbox](docs/Checkbox.md)
60
+ - [Dialog](docs/Dialog.md)
61
+ - [Drawer](docs/Drawer.md)
62
+ - [Footer](docs/Footer.md)
63
+ - [Header](docs/Header.md)
64
+ - [Highlight](docs/Highlight.md)
65
+ - [Icon](docs/Icon.md)
66
+ - [IconButton](docs/IconButton.md)
67
+ - [List](docs/List.md) (covers List and ListItem)
68
+ - [Modal](docs/Modal.md)
69
+ - [Odometer](docs/Odometer.md) (component + useOdometer hook)
70
+ - [ScrollArea](docs/ScrollArea.md)
71
+ - [SvgSprite](docs/SvgSprite.md)
72
+ - [Switch](docs/Switch.md)
73
+ - [Tag](docs/Tag.md)
74
+ - [TextArea](docs/TextArea.md)
75
+ - [TextField](docs/TextField.md)
76
+ - [Toast](docs/Toast.md)
77
+ - [View](docs/View.md)
78
+ - [ViewDrawer](docs/ViewDrawer.md)
79
+ - [ViewModal](docs/ViewModal.md)
80
+ - [Viewport](docs/Viewport.md) (ViewportProvider + useViewport)
81
+
82
+ Notes:
83
+
84
+ - Each CSS variables table lists only component-scoped variables with exact fallback chains from the corresponding \*
85
+ .module.scss file.
86
+ - Where a component wraps a Radix UI primitive, the doc links to the official Radix docs and lists common props.
87
+
71
88
  ## Basic Usage
72
89
 
73
90
  ```jsx
@@ -92,9 +109,13 @@ export default App;
92
109
 
93
110
  ## Integration
94
111
 
95
- **Addon UI** is designed exclusively for the Addon Bone framework and does not have a standalone build as it's connected as a plugin. This library is an integral part of the Addon Bone ecosystem for developing browser extensions with a shared codebase.
112
+ **Addon UI** is designed exclusively for the [Addon Bone](https://addonbone.com) framework and does not have a standalone build as it's connected
113
+ as a plugin. This library is an integral part of the Addon Bone ecosystem for developing browser extensions with a
114
+ shared codebase.
96
115
 
97
- Addon Bone is a framework for developing browser extensions with a common codebase. This means you can create multiple extensions with the same functionality but with different designs, localizations, and feature sets depending on the needs of each extension while maintaining access to a shared codebase.
116
+ [Addon Bone](https://addonbone.com) is a framework for developing browser extensions with a common codebase. This means you can create multiple
117
+ extensions with the same functionality but with different designs, localizations, and feature sets depending on the
118
+ needs of each extension while maintaining access to a shared codebase.
98
119
 
99
120
  ### Plugin Setup
100
121
 
@@ -118,16 +139,22 @@ export default defineConfig({
118
139
 
119
140
  ### Configuration Files
120
141
 
121
- The `addon-ui` configuration is designed to retrieve configuration from each extension separately, allowing for different designs for different extensions without changing any code. You only need to modify the configuration, style variables, and icons.
142
+ The `addon-ui` configuration is designed to retrieve configuration from each extension separately, allowing for
143
+ different designs for different extensions without changing any code. You only need to modify the configuration, style
144
+ variables, and icons.
122
145
 
123
- The plugin looks for configuration files in specific directories within your project. By default, it searches in the following locations (in order of priority):
146
+ The plugin looks for configuration files in specific directories within your project. By default, it searches in the
147
+ following locations (in order of priority):
124
148
 
125
149
  1. **App-specific directory**: `src/apps/[app-name]/[app-src-dir]/[theme-dir]`
126
150
  2. **Shared directory**: `src/shared/[theme-dir]`
127
151
 
128
152
  Where `[theme-dir]` is the directory specified in the `themeDir` option (defaults to the current directory).
129
153
 
130
- The `mergeConfig` option (default: `true`) determines whether configurations from multiple directories should be merged. When enabled, configurations from both app-specific and shared directories will be combined, with app-specific values taking precedence in case of conflicts. If disabled, only the first configuration found will be used (with app-specific having priority).
154
+ The `mergeConfig` option (default: `true`) determines whether configurations from multiple directories should be merged.
155
+ When enabled, configurations from both app-specific and shared directories will be combined, with app-specific values
156
+ taking precedence in case of conflicts. If disabled, only the first configuration found will be used (with app-specific
157
+ having priority).
131
158
 
132
159
  You can create these files to customize the UI components:
133
160
 
@@ -169,7 +196,9 @@ The configuration can also include SVG icons imported directly from your project
169
196
 
170
197
  #### ui.style.scss
171
198
 
172
- Similar to configuration files, style files are also searched for in the same directories with the same priority order. The `mergeStyles` option (default: `true`) works the same way as `mergeConfig`, allowing styles from multiple directories to be combined when enabled.
199
+ Similar to configuration files, style files are also searched for in the same directories with the same priority order.
200
+ The `mergeStyles` option (default: `true`) works the same way as `mergeConfig`, allowing styles from multiple
201
+ directories to be combined when enabled.
173
202
 
174
203
  ```scss
175
204
  // src/shared/theme/ui.style.scss
@@ -230,7 +259,9 @@ Similar to configuration files, style files are also searched for in the same di
230
259
 
231
260
  ## Customization
232
261
 
233
- The `addon-ui` library allows for extensive customization to create different designs for different extensions without changing code. This is particularly useful in the Addon Bone framework where you might need to maintain multiple browser extensions with the same functionality but different visual appearances.
262
+ The `addon-ui` library allows for extensive customization to create different designs for different extensions without
263
+ changing code. This is particularly useful in the Addon Bone framework where you might need to maintain multiple browser
264
+ extensions with the same functionality but different visual appearances.
234
265
 
235
266
  ### Global Theme Customization
236
267
 
@@ -261,11 +292,14 @@ function App() {
261
292
 
262
293
  ### Using Extra Props
263
294
 
264
- Extra Props is a powerful feature that allows you to extend component props with custom properties. This is particularly useful when you need to add custom functionality or data to components across your application without modifying the original component code.
295
+ Extra Props is a powerful feature that allows you to extend component props with custom properties. This is particularly
296
+ useful when you need to add custom functionality or data to components across your application without modifying the
297
+ original component code.
265
298
 
266
299
  #### What are Extra Props?
267
300
 
268
- Extra Props provide a way to pass additional properties to components throughout your application using React Context. This allows you to:
301
+ Extra Props provide a way to pass additional properties to components throughout your application using React Context.
302
+ This allows you to:
269
303
 
270
304
  - Add application-specific properties to UI components
271
305
  - Share common data across multiple components
@@ -317,7 +351,8 @@ function AppHeader() {
317
351
 
318
352
  #### Example Use Case
319
353
 
320
- A common use case for Extra Props is to add application-specific configuration to UI components. For example, you might want to add custom analytics tracking to buttons:
354
+ A common use case for Extra Props is to add application-specific configuration to UI components. For example, you might
355
+ want to add custom analytics tracking to buttons:
321
356
 
322
357
  ```jsx
323
358
  import {Button, useExtra} from "addon-ui";
@@ -360,7 +395,8 @@ declare module "addon-ui" {
360
395
  }
361
396
  ```
362
397
 
363
- With this type definition, TypeScript will provide proper type checking and autocompletion when using the `useExtra` hook:
398
+ With this type definition, TypeScript will provide proper type checking and autocompletion when using the `useExtra`
399
+ hook:
364
400
 
365
401
  ```tsx
366
402
  import React from "react";
@@ -392,806 +428,42 @@ function App() {
392
428
  }
393
429
  ```
394
430
 
395
- ## Component Examples
396
-
397
- ### Buttons
398
-
399
- ```jsx
400
- import {Button, ButtonColor, ButtonSize, ButtonVariant} from 'addon-ui';
401
-
402
- // Basic button
403
- <Button>Click me</Button>
404
-
405
- // Variants
406
- <Button variant={ButtonVariant.Contained}>Contained</Button>
407
- <Button variant={ButtonVariant.Outlined}>Outlined</Button>
408
- <Button variant={ButtonVariant.Text}>Text</Button>
409
-
410
- // Colors
411
- <Button color={ButtonColor.Primary}>Primary</Button>
412
- <Button color={ButtonColor.Secondary}>Secondary</Button>
413
- <Button color={ButtonColor.Accent}>Accent</Button>
414
-
415
- // Sizes
416
- <Button size={ButtonSize.Small}>Small</Button>
417
- <Button size={ButtonSize.Medium}>Medium</Button>
418
- <Button size={ButtonSize.Large}>Large</Button>
419
-
420
- // Disabled state
421
- <Button disabled>Disabled</Button>
422
- ```
423
-
424
- ### Form Components
425
-
426
- ```jsx
427
- import {TextField, TextArea, Checkbox, Switch} from 'addon-ui';
428
-
429
- // Text input
430
- <TextField label="Username" placeholder="Enter username" />
431
-
432
- // Text area
433
- <TextArea label="Description" placeholder="Enter description" />
434
-
435
- // Checkbox
436
- <Checkbox label="Remember me" />
437
-
438
- // Switch
439
- <Switch label="Enable notifications" />
440
- ```
441
-
442
- ### Layout Components
443
-
444
- ```jsx
445
- import {Layout, Header, Footer} from "addon-ui";
446
-
447
- <Layout>
448
- <Header>My Application</Header>
449
- <div>Content goes here</div>
450
- <Footer>© 2023 My Company</Footer>
451
- </Layout>;
452
- ```
453
-
454
- ### Feedback Components
455
-
456
- ```jsx
457
- import {Toast, Modal, Dialog, Drawer} from 'addon-ui';
458
-
459
- // Toast notification
460
- <Toast message="Operation successful!" />
461
-
462
- // Modal dialog
463
- <Modal open={isOpen} onClose={handleClose}>
464
- <h2>Modal Title</h2>
465
- <p>Modal content goes here</p>
466
- </Modal>
467
-
468
- // Confirmation dialog
469
- <Dialog
470
- title="Confirm Action"
471
- content="Are you sure you want to proceed?"
472
- confirmText="Yes"
473
- cancelText="No"
474
- onConfirm={handleConfirm}
475
- onCancel={handleCancel}
476
- />
477
-
478
- // Side drawer
479
- <Drawer open={isOpen} onClose={handleClose} position="right">
480
- <h2>Drawer Content</h2>
481
- <p>Drawer content goes here</p>
482
- </Drawer>
483
- ```
484
-
485
- ## Supported Components
486
-
487
- ### Button
488
-
489
- The Button component provides a customizable button with various styles, colors, and sizes.
490
-
491
- #### Props
492
-
493
- | Prop | Type | Description |
494
- | ----------------- | ------------- | ----------------------------------------- |
495
- | variant | ButtonVariant | Button style variant |
496
- | color | ButtonColor | Button color |
497
- | size | ButtonSize | Button size |
498
- | radius | ButtonRadius | Button border radius |
499
- | after | ReactNode | Content to display after the button text |
500
- | before | ReactNode | Content to display before the button text |
501
- | afterClassName | string | Class name for the after content |
502
- | beforeClassName | string | Class name for the before content |
503
- | childrenClassName | string | Class name for the children content |
504
-
505
- #### Enums
506
-
507
- ```jsx
508
- // Available variants
509
- ButtonVariant.Contained;
510
- ButtonVariant.Outlined;
511
- ButtonVariant.Text;
512
-
513
- // Available colors
514
- ButtonColor.Primary;
515
- ButtonColor.Secondary;
516
- ButtonColor.Accent;
517
-
518
- // Available sizes
519
- ButtonSize.Small;
520
- ButtonSize.Medium;
521
- ButtonSize.Large;
522
-
523
- // Available radius options
524
- ButtonRadius.Small;
525
- ButtonRadius.Medium;
526
- ButtonRadius.Large;
527
- ButtonRadius.Full;
528
- ```
529
-
530
- #### Example
531
-
532
- ```jsx
533
- import {Button, ButtonVariant, ButtonColor, ButtonSize, ButtonRadius} from "addon-ui";
534
-
535
- <Button
536
- variant={ButtonVariant.Contained}
537
- color={ButtonColor.Primary}
538
- size={ButtonSize.Medium}
539
- radius={ButtonRadius.Medium}
540
- >
541
- Click me
542
- </Button>;
543
- ```
544
-
545
- ### TextField
546
-
547
- The TextField component provides a customizable text input field with various styles, sizes, and validation states.
548
-
549
- #### Props
550
-
551
- | Prop | Type | Description |
552
- | --------------- | ---------------- | ---------------------------------------- |
553
- | variant | TextFieldVariant | Input style variant |
554
- | accent | TextFieldAccent | Input accent color for validation states |
555
- | radius | TextFieldRadius | Input border radius |
556
- | customSize | TextFieldSize | Input size |
557
- | label | string | Input label |
558
- | fullWidth | boolean | Whether the input should take full width |
559
- | before | ReactNode | Content to display before the input |
560
- | after | ReactNode | Content to display after the input |
561
- | inputClassName | string | Class name for the input element |
562
- | afterClassName | string | Class name for the after content |
563
- | beforeClassName | string | Class name for the before content |
564
-
565
- #### Enums
566
-
567
- ```jsx
568
- // Available variants
569
- TextFieldVariant.Regular;
570
- TextFieldVariant.Outlined;
571
- TextFieldVariant.Filled;
572
-
573
- // Available sizes
574
- TextFieldSize.Small;
575
- TextFieldSize.Medium;
576
- TextFieldSize.Large;
577
-
578
- // Available radius options
579
- TextFieldRadius.None;
580
- TextFieldRadius.Small;
581
- TextFieldRadius.Medium;
582
- TextFieldRadius.Large;
583
- TextFieldRadius.Full;
584
-
585
- // Available accent options
586
- TextFieldAccent.Success;
587
- TextFieldAccent.Error;
588
- ```
589
-
590
- #### Example
591
-
592
- ```jsx
593
- import {TextField, TextFieldVariant, TextFieldSize, TextFieldRadius, TextFieldAccent} from "addon-ui";
594
-
595
- <TextField
596
- variant={TextFieldVariant.Outlined}
597
- customSize={TextFieldSize.Medium}
598
- radius={TextFieldRadius.Medium}
599
- accent={TextFieldAccent.Success}
600
- label="Username"
601
- placeholder="Enter your username"
602
- fullWidth
603
- />;
604
- ```
605
-
606
- ### TextArea
607
-
608
- The TextArea component provides a customizable multi-line text input with auto-resizing capability.
609
-
610
- #### Props
611
-
612
- | Prop | Type | Description |
613
- | --------- | --------------- | ------------------------------------------- |
614
- | variant | TextAreaVariant | TextArea style variant |
615
- | radius | TextAreaRadius | TextArea border radius |
616
- | size | TextAreaSize | TextArea size |
617
- | fullWidth | boolean | Whether the textarea should take full width |
618
- | label | string | TextArea label |
619
-
620
- #### Enums
621
-
622
- ```jsx
623
- // Available variants
624
- TextAreaVariant.Regular;
625
- TextAreaVariant.Outlined;
626
- TextAreaVariant.Filled;
627
-
628
- // Available sizes
629
- TextAreaSize.Small;
630
- TextAreaSize.Medium;
631
- TextAreaSize.Large;
632
-
633
- // Available radius options
634
- TextAreaRadius.None;
635
- TextAreaRadius.Small;
636
- TextAreaRadius.Medium;
637
- TextAreaRadius.Large;
638
- ```
639
-
640
- #### Example
641
-
642
- ```jsx
643
- import {TextArea, TextAreaVariant, TextAreaSize, TextAreaRadius} from "addon-ui";
644
-
645
- <TextArea
646
- variant={TextAreaVariant.Outlined}
647
- size={TextAreaSize.Medium}
648
- radius={TextAreaRadius.Medium}
649
- label="Description"
650
- placeholder="Enter description"
651
- rows={4}
652
- fullWidth
653
- />;
654
- ```
655
-
656
- ### Checkbox
657
-
658
- The Checkbox component provides a customizable checkbox with various styles and sizes.
659
-
660
- #### Props
661
-
662
- | Prop | Type | Description |
663
- | ------------------ | --------------- | ------------------------------------ |
664
- | indicatorClassName | string | Class name for the indicator element |
665
- | size | CheckboxSize | Checkbox size |
666
- | radius | CheckboxRadius | Checkbox border radius |
667
- | variant | CheckboxVariant | Checkbox style variant |
668
- | checkedIcon | ReactElement | Custom icon for checked state |
669
- | indeterminateIcon | ReactElement | Custom icon for indeterminate state |
670
-
671
- #### Enums
672
-
673
- ```jsx
674
- // Available variants
675
- CheckboxVariant.Classic;
676
- CheckboxVariant.Soft;
677
-
678
- // Available sizes
679
- CheckboxSize.Small;
680
- CheckboxSize.Medium;
681
- CheckboxSize.Large;
682
-
683
- // Available radius options
684
- CheckboxRadius.Small;
685
- CheckboxRadius.Large;
686
- ```
687
-
688
- #### Example
689
-
690
- ```jsx
691
- import {Checkbox, CheckboxVariant, CheckboxSize, CheckboxRadius} from "addon-ui";
692
-
693
- <Checkbox variant={CheckboxVariant.Classic} size={CheckboxSize.Medium} radius={CheckboxRadius.Small} checked={true} />;
694
- ```
695
-
696
- ### Switch
697
-
698
- The Switch component provides a toggle switch control.
699
-
700
- #### Props
701
-
702
- | Prop | Type | Description |
703
- | -------------- | ------ | -------------------------------- |
704
- | thumbClassName | string | Class name for the thumb element |
705
-
706
- #### Example
707
-
708
- ```jsx
709
- import {Switch} from "addon-ui";
710
-
711
- <Switch checked={isEnabled} onCheckedChange={setIsEnabled} />;
712
- ```
713
-
714
- ### Avatar
715
-
716
- The Avatar component displays a user's profile picture or a fallback when the image is not available.
717
-
718
- #### Props
719
-
720
- | Prop | Type | Description |
721
- | ----------------- | ------------ | -------------------------------------------------- |
722
- | size | AvatarSize | Avatar size |
723
- | radius | AvatarRadius | Avatar border radius |
724
- | fallback | ReactNode | Content to display when the image is not available |
725
- | fallbackClassName | string | Class name for the fallback content |
726
- | imageClassName | string | Class name for the image element |
727
- | cursorPointer | boolean | Whether the avatar should have a pointer cursor |
728
- | delayMs | number | Delay before showing the fallback content |
729
-
730
- #### Enums
731
-
732
- ```jsx
733
- // Available sizes
734
- AvatarSize.Small;
735
- AvatarSize.Medium;
736
- AvatarSize.Large;
737
-
738
- // Available radius options
739
- AvatarRadius.Small;
740
- AvatarRadius.Medium;
741
- AvatarRadius.Large;
742
- ```
743
-
744
- #### Example
745
-
746
- ```jsx
747
- import {Avatar, AvatarSize, AvatarRadius} from "addon-ui";
748
-
749
- <Avatar
750
- src="https://example.com/avatar.jpg"
751
- alt="User Avatar"
752
- size={AvatarSize.Medium}
753
- radius={AvatarRadius.Medium}
754
- fallback="JD"
755
- />;
756
- ```
757
-
758
- ### BaseButton
759
-
760
- The BaseButton component is a foundational button component that provides basic button functionality.
761
-
762
- #### Props
763
-
764
- | Prop | Type | Description |
765
- | ----------------- | --------- | ----------------------------------------- |
766
- | after | ReactNode | Content to display after the button text |
767
- | before | ReactNode | Content to display before the button text |
768
- | afterClassName | string | Class name for the after content |
769
- | beforeClassName | string | Class name for the before content |
770
- | childrenClassName | string | Class name for the children content |
771
-
772
- #### Example
773
-
774
- ```jsx
775
- import {BaseButton} from "addon-ui";
776
-
777
- <BaseButton before={<Icon name="star" />} after={<Icon name="arrow-right" />}>
778
- Click me
779
- </BaseButton>;
780
- ```
781
-
782
- ### Dialog
783
-
784
- The Dialog component displays a modal dialog that overlays the page content.
785
-
786
- #### Props
787
-
788
- | Prop | Type | Description |
789
- | ----------------- | ----------- | -------------------------------------------------------------- |
790
- | speed | number | Animation speed in milliseconds |
791
- | description | string | Dialog description (for accessibility) |
792
- | fullscreen | boolean | Whether the dialog should be fullscreen |
793
- | overlayClassName | string | Class name for the overlay element |
794
- | childrenClassName | string | Class name for the children content |
795
- | open | boolean | Whether the dialog is open |
796
- | onOpenChange | function | Callback when the open state changes |
797
- | modal | boolean | Whether the dialog is modal (blocks interaction with the page) |
798
- | container | HTMLElement | Container element for the dialog |
799
- | title | string | Dialog title (for accessibility) |
800
-
801
- #### Example
802
-
803
- ```jsx
804
- import {Dialog} from "addon-ui";
805
-
806
- <Dialog open={isOpen} onOpenChange={setIsOpen} title="Confirmation" description="Please confirm your action">
807
- <div>
808
- <h2>Are you sure?</h2>
809
- <p>This action cannot be undone.</p>
810
- <div>
811
- <Button onClick={() => setIsOpen(false)}>Cancel</Button>
812
- <Button onClick={handleConfirm}>Confirm</Button>
813
- </div>
814
- </div>
815
- </Dialog>;
816
- ```
817
-
818
- ### Drawer
819
-
820
- The Drawer component displays a sliding panel that comes from the edge of the screen.
821
-
822
- #### Props
823
-
824
- | Prop | Type | Description |
825
- | -------- | -------------------------------------- | ---------------------------------- |
826
- | position | 'left' \| 'right' \| 'top' \| 'bottom' | Position of the drawer |
827
- | open | boolean | Whether the drawer is open |
828
- | onClose | function | Callback when the drawer is closed |
829
-
830
- #### Example
831
-
832
- ```jsx
833
- import {Drawer} from "addon-ui";
834
-
835
- <Drawer open={isOpen} onClose={() => setIsOpen(false)} position="right">
836
- <div>Drawer content</div>
837
- </Drawer>;
838
- ```
839
-
840
- ### Footer
841
-
842
- The Footer component provides a consistent footer layout.
843
-
844
- #### Example
845
-
846
- ```jsx
847
- import {Footer} from "addon-ui";
848
-
849
- <Footer>
850
- <div>© 2023 My Company</div>
851
- </Footer>;
852
- ```
853
-
854
- ### Header
855
-
856
- The Header component provides a consistent header layout.
857
-
858
- #### Example
859
-
860
- ```jsx
861
- import {Header} from "addon-ui";
862
-
863
- <Header>
864
- <div>My Application</div>
865
- </Header>;
866
- ```
867
-
868
- ### Highlight
869
-
870
- The Highlight component highlights text matches within content.
871
-
872
- #### Props
873
-
874
- | Prop | Type | Description |
875
- | ------------------ | -------- | ------------------------------- |
876
- | searchWords | string[] | Words to highlight |
877
- | textToHighlight | string | Text content to search within |
878
- | highlightClassName | string | Class name for highlighted text |
879
-
880
- #### Example
881
-
882
- ```jsx
883
- import {Highlight} from "addon-ui";
884
-
885
- <Highlight searchWords={["react", "component"]} textToHighlight="This is a React component library" />;
886
- ```
887
-
888
- ### Icon
889
-
890
- The Icon component displays vector icons.
891
-
892
- #### Props
893
-
894
- | Prop | Type | Description |
895
- | ----- | ------ | ----------- |
896
- | name | string | Icon name |
897
- | size | number | Icon size |
898
- | color | string | Icon color |
899
-
900
- #### Example
901
-
902
- ```jsx
903
- import {Icon} from "addon-ui";
904
-
905
- <Icon name="star" size={24} color="#f5a623" />;
906
- ```
907
-
908
- ### IconButton
909
-
910
- The IconButton component combines an icon with button functionality.
911
-
912
- #### Props
913
-
914
- | Prop | Type | Description |
915
- | ----- | ------------------------------------ | --------------- |
916
- | icon | ReactNode | Icon to display |
917
- | size | 'small' \| 'medium' \| 'large' | Button size |
918
- | color | 'primary' \| 'secondary' \| 'accent' | Button color |
919
-
920
- #### Example
921
-
922
- ```jsx
923
- import {IconButton, Icon} from "addon-ui";
924
-
925
- <IconButton icon={<Icon name="star" />} size="medium" color="primary" onClick={handleClick} />;
926
- ```
927
-
928
- ### Layout
929
-
930
- The Layout component provides a consistent page layout structure.
931
-
932
- #### Example
933
-
934
- ```jsx
935
- import {Layout, Header, Footer} from "addon-ui";
936
-
937
- <Layout>
938
- <Header>My Application</Header>
939
- <div>Content goes here</div>
940
- <Footer>© 2023 My Company</Footer>
941
- </Layout>;
942
- ```
943
-
944
- ### List
945
-
946
- The List component displays a list of items.
947
-
948
- #### Props
949
-
950
- | Prop | Type | Description |
951
- | ------- | ---------------------------------- | --------------------- |
952
- | variant | 'ordered' \| 'unordered' | List type |
953
- | spacing | 'compact' \| 'normal' \| 'relaxed' | Spacing between items |
954
-
955
- #### Example
956
-
957
- ```jsx
958
- import {List, ListItem} from "addon-ui";
959
-
960
- <List variant="unordered" spacing="normal">
961
- <ListItem>Item 1</ListItem>
962
- <ListItem>Item 2</ListItem>
963
- <ListItem>Item 3</ListItem>
964
- </List>;
965
- ```
966
-
967
- ### ListItem
968
-
969
- The ListItem component represents an item in a List.
970
-
971
- #### Example
972
-
973
- ```jsx
974
- import {ListItem} from "addon-ui";
975
-
976
- <ListItem>Item content</ListItem>;
977
- ```
978
-
979
- ### Modal
980
-
981
- The Modal component displays content in a layer above the page.
982
-
983
- #### Props
984
-
985
- | Prop | Type | Description |
986
- | ------- | --------- | --------------------------------- |
987
- | open | boolean | Whether the modal is open |
988
- | onClose | function | Callback when the modal is closed |
989
- | title | string | Modal title |
990
- | footer | ReactNode | Modal footer content |
991
-
992
- #### Example
993
-
994
- ```jsx
995
- import {Modal, Button} from "addon-ui";
996
-
997
- <Modal
998
- open={isOpen}
999
- onClose={() => setIsOpen(false)}
1000
- title="Modal Title"
1001
- footer={<Button onClick={() => setIsOpen(false)}>Close</Button>}
1002
- >
1003
- <p>Modal content goes here</p>
1004
- </Modal>;
1005
- ```
1006
-
1007
- ### Odometer
1008
-
1009
- The Odometer component displays animated number transitions.
1010
-
1011
- #### Props
431
+ ---
1012
432
 
1013
- | Prop | Type | Description |
1014
- | -------- | ------ | ---------------------------------- |
1015
- | value | number | Current value to display |
1016
- | format | string | Number format |
1017
- | duration | number | Animation duration in milliseconds |
433
+ ## Theming and style reuse
1018
434
 
1019
- #### Example
1020
-
1021
- ```jsx
1022
- import {Odometer} from "addon-ui";
1023
-
1024
- <Odometer value={1234} format="(,ddd)" duration={1000} />;
1025
- ```
1026
-
1027
- ### ScrollArea
1028
-
1029
- The ScrollArea component provides a customizable scrollable area.
1030
-
1031
- #### Props
1032
-
1033
- | Prop | Type | Description |
1034
- | --------------- | ----------------------------------------- | ------------------------------ |
1035
- | type | 'auto' \| 'always' \| 'scroll' \| 'hover' | When to show scrollbars |
1036
- | scrollHideDelay | number | Delay before hiding scrollbars |
1037
-
1038
- #### Example
1039
-
1040
- ```jsx
1041
- import {ScrollArea} from "addon-ui";
1042
-
1043
- <ScrollArea type="hover" scrollHideDelay={800} style={{height: 200}}>
1044
- <div>Content that might overflow</div>
1045
- </ScrollArea>;
1046
- ```
1047
-
1048
- ### SvgSprite
1049
-
1050
- The SvgSprite component manages SVG sprite definitions.
1051
-
1052
- #### Example
1053
-
1054
- ```jsx
1055
- import {SvgSprite} from "addon-ui";
1056
-
1057
- <SvgSprite />;
1058
- ```
1059
-
1060
- ### Tag
1061
-
1062
- The Tag component displays a label or category tag.
1063
-
1064
- #### Props
1065
-
1066
- | Prop | Type | Description |
1067
- | ------- | ------------------------------------------------------------- | ----------------------------------------- |
1068
- | color | 'primary' \| 'secondary' \| 'success' \| 'warning' \| 'error' | Tag color |
1069
- | size | 'small' \| 'medium' \| 'large' | Tag size |
1070
- | onClose | function | Callback when the close button is clicked |
1071
-
1072
- #### Example
1073
-
1074
- ```jsx
1075
- import {Tag} from "addon-ui";
1076
-
1077
- <Tag color="primary" size="medium" onClose={handleClose}>
1078
- Featured
1079
- </Tag>;
1080
- ```
1081
-
1082
- ### Toast
1083
-
1084
- The Toast component displays brief notifications.
1085
-
1086
- #### Props
1087
-
1088
- | Prop | Type | Description |
1089
- | -------- | --------------------------------------------------------------------------------- | ------------------------ |
1090
- | message | string | Toast message |
1091
- | type | 'info' \| 'success' \| 'warning' \| 'error' | Toast type |
1092
- | duration | number | Duration in milliseconds |
1093
- | position | 'top' \| 'bottom' \| 'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right' | Toast position |
1094
-
1095
- #### Example
1096
-
1097
- ```jsx
1098
- import {Toast} from "addon-ui";
1099
-
1100
- <Toast message="Operation successful!" type="success" duration={3000} position="top-right" />;
1101
- ```
1102
-
1103
- ### Tooltip
1104
-
1105
- The Tooltip component displays informative text when hovering over an element.
1106
-
1107
- #### Props
1108
-
1109
- | Prop | Type | Description |
1110
- | -------- | -------------------------------------- | -------------------------------- |
1111
- | content | ReactNode | Tooltip content |
1112
- | position | 'top' \| 'bottom' \| 'left' \| 'right' | Tooltip position |
1113
- | delay | number | Delay before showing the tooltip |
1114
-
1115
- #### Example
1116
-
1117
- ```jsx
1118
- import {Tooltip, Button} from "addon-ui";
1119
-
1120
- <Tooltip content="More information" position="top" delay={300}>
1121
- <Button>Hover me</Button>
1122
- </Tooltip>;
1123
- ```
1124
-
1125
- ### View
1126
-
1127
- The View component provides a container for content with consistent styling.
1128
-
1129
- #### Example
1130
-
1131
- ```jsx
1132
- import {View} from "addon-ui";
1133
-
1134
- <View>
1135
- <h1>Page Title</h1>
1136
- <p>Page content</p>
1137
- </View>;
1138
- ```
1139
-
1140
- ### ViewDrawer
1141
-
1142
- The ViewDrawer component combines View and Drawer components.
1143
-
1144
- #### Example
1145
-
1146
- ```jsx
1147
- import {ViewDrawer} from "addon-ui";
1148
-
1149
- <ViewDrawer open={isOpen} onClose={() => setIsOpen(false)} position="right">
1150
- <h1>Drawer Title</h1>
1151
- <p>Drawer content</p>
1152
- </ViewDrawer>;
1153
- ```
1154
-
1155
- ### ViewModal
1156
-
1157
- The ViewModal component combines View and Modal components.
1158
-
1159
- #### Example
1160
-
1161
- ```jsx
1162
- import {ViewModal} from "addon-ui";
1163
-
1164
- <ViewModal open={isOpen} onClose={() => setIsOpen(false)} title="Modal Title">
1165
- <p>Modal content</p>
1166
- </ViewModal>;
1167
- ```
435
+ - Global theme tokens (colors, typography, spacing, transitions) live in your ui.style.scss. Components consume them
436
+ through fallbacks.
437
+ - Each component also exposes its own `--component-*` variables. See the CSS variables tables in the docs to know
438
+ exactly what you can override.
439
+ - Light/dark modes: use `@import "addon-ui/theme";` and the provided `@include light { ... }` / `@include dark { ... }`
440
+ mixins in your theme SCSS to scope tokens per color scheme.
1168
441
 
1169
- ## Component Props
442
+ ## Radix UI and third-party integrations
1170
443
 
1171
- All components accept standard HTML attributes in addition to their specific props. Here are some common props for key components:
444
+ Several components are built on Radix primitives (Dialog, Checkbox, ScrollArea, Switch, Toast) or wrap third-party
445
+ tools (react-highlight-words, odometer). Each doc links to the official API and explains which props you can pass
446
+ through.
1172
447
 
1173
- ### Button
448
+ ## Icons and sprite
1174
449
 
1175
- | Prop | Type | Default | Description |
1176
- | -------- | ---------------------------------------- | ----------- | ------------------------------ |
1177
- | variant | 'contained' \| 'outlined' \| 'text' | 'contained' | Button style variant |
1178
- | color | 'primary' \| 'secondary' \| 'accent' | undefined | Button color |
1179
- | size | 'small' \| 'medium' \| 'large' | undefined | Button size |
1180
- | radius | 'small' \| 'medium' \| 'large' \| 'full' | undefined | Button border radius |
1181
- | disabled | boolean | false | Whether the button is disabled |
450
+ - Register icons in `ui.config.ts` or via `UIProvider`’s `icons` prop. The Icon component pulls symbols from the
451
+ automatically mounted SvgSprite.
452
+ - Icons are lazily registered: a symbol is added only after an Icon with that name renders at least once.
453
+ - See docs/Icon.md and docs/SvgSprite.md for details and examples.
1182
454
 
1183
- ### TextField
455
+ ## Extra props (cross-cutting configuration)
1184
456
 
1185
- | Prop | Type | Default | Description |
1186
- | ----------- | -------- | --------- | ------------------------------ |
1187
- | label | string | undefined | Input label |
1188
- | placeholder | string | undefined | Input placeholder |
1189
- | value | string | undefined | Input value |
1190
- | onChange | function | undefined | Change event handler |
1191
- | error | boolean | false | Whether the input has an error |
1192
- | helperText | string | undefined | Helper text to display |
1193
- | disabled | boolean | false | Whether the input is disabled |
457
+ Use the `extra` field in `ui.config.ts` to supply app-wide values (feature flags, labels, analytics switches) and access
458
+ them at runtime with the `useExtra()` hook. You can augment the `ExtraProps` TypeScript interface by declaration merging
459
+ for full type safety.
1194
460
 
1195
- ## License
461
+ ## Contributing
1196
462
 
1197
- This project is licensed under the MIT License - see the LICENSE file for details.
463
+ - Keep canonical end-user documentation in the `docs/` directory. When adding or changing CSS variables in a component’s
464
+ `*.module.scss`, update the corresponding doc table.
465
+ - Where a component wraps a Radix primitive, keep the “Radix UI props” section in sync if the underlying package
466
+ changes.
467
+ - Consider adding a short README stub inside each component folder that links to the canonical doc (optional for
468
+ discoverability during development).
469
+ - Run and maintain Storybook stories (if present) to validate visual changes.