spaper 1.4.0 → 2.0.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 (206) hide show
  1. package/README.md +20 -59
  2. package/dist/components/Alert.svelte +83 -0
  3. package/dist/components/Alert.svelte.d.ts +15 -0
  4. package/dist/components/Article.svelte +63 -0
  5. package/dist/components/Article.svelte.d.ts +17 -0
  6. package/dist/components/Avatar/Avatar.svelte +102 -0
  7. package/dist/components/Avatar/Avatar.svelte.d.ts +16 -0
  8. package/dist/components/Avatar/AvatarGroup.svelte +21 -0
  9. package/dist/components/Avatar/AvatarGroup.svelte.d.ts +9 -0
  10. package/dist/components/Avatar/index.d.ts +2 -0
  11. package/dist/components/Avatar/index.js +2 -0
  12. package/dist/components/Breadcrumb.svelte +33 -0
  13. package/dist/components/Breadcrumb.svelte.d.ts +12 -0
  14. package/dist/components/Button.svelte +174 -0
  15. package/dist/components/Button.svelte.d.ts +33 -0
  16. package/dist/components/Card.svelte +101 -0
  17. package/dist/components/Card.svelte.d.ts +22 -0
  18. package/dist/components/Carousel/Carousel.svelte +204 -0
  19. package/dist/components/Carousel/Carousel.svelte.d.ts +27 -0
  20. package/dist/components/Carousel/CarouselItem.svelte +48 -0
  21. package/dist/components/Carousel/CarouselItem.svelte.d.ts +7 -0
  22. package/{components → dist/components}/Carousel/index.d.ts +1 -0
  23. package/dist/components/Carousel/types.d.ts +22 -0
  24. package/dist/components/CloseButton.svelte +34 -0
  25. package/dist/components/CloseButton.svelte.d.ts +8 -0
  26. package/dist/components/Collapsible.svelte +64 -0
  27. package/dist/components/Collapsible.svelte.d.ts +16 -0
  28. package/dist/components/CopyButton.svelte +54 -0
  29. package/dist/components/CopyButton.svelte.d.ts +13 -0
  30. package/dist/components/Divider.svelte +9 -0
  31. package/dist/components/Divider.svelte.d.ts +6 -0
  32. package/dist/components/Form/Checkbox.svelte +54 -0
  33. package/dist/components/Form/Checkbox.svelte.d.ts +15 -0
  34. package/dist/components/Form/Input.svelte +105 -0
  35. package/dist/components/Form/Input.svelte.d.ts +21 -0
  36. package/dist/components/Form/NumberInput/DecrementButton.svelte +14 -0
  37. package/dist/components/Form/NumberInput/DecrementButton.svelte.d.ts +9 -0
  38. package/dist/components/Form/NumberInput/IncrementButton.svelte +14 -0
  39. package/dist/components/Form/NumberInput/IncrementButton.svelte.d.ts +9 -0
  40. package/dist/components/Form/NumberInput/NumberInput.svelte +227 -0
  41. package/dist/components/Form/NumberInput/NumberInput.svelte.d.ts +34 -0
  42. package/dist/components/Form/Radio.svelte +42 -0
  43. package/dist/components/Form/Radio.svelte.d.ts +13 -0
  44. package/dist/components/Form/Select.svelte +61 -0
  45. package/dist/components/Form/Select.svelte.d.ts +12 -0
  46. package/dist/components/Form/Slider.svelte +129 -0
  47. package/dist/components/Form/Slider.svelte.d.ts +22 -0
  48. package/dist/components/Form/Switch.svelte +101 -0
  49. package/dist/components/Form/Switch.svelte.d.ts +22 -0
  50. package/dist/components/Form/index.d.ts +9 -0
  51. package/{components → dist/components}/Form/index.js +1 -2
  52. package/dist/components/Hero.svelte +78 -0
  53. package/dist/components/Hero.svelte.d.ts +17 -0
  54. package/dist/components/Icon.svelte +102 -0
  55. package/dist/components/Icon.svelte.d.ts +27 -0
  56. package/dist/components/Modal/Modal.svelte +120 -0
  57. package/dist/components/Modal/Modal.svelte.d.ts +19 -0
  58. package/dist/components/Modal/index.d.ts +12 -0
  59. package/dist/components/Modal/index.js +30 -0
  60. package/dist/components/Navbar.svelte +98 -0
  61. package/dist/components/Navbar.svelte.d.ts +11 -0
  62. package/dist/components/Pagination/Arrow.svelte +29 -0
  63. package/dist/components/Pagination/Arrow.svelte.d.ts +8 -0
  64. package/dist/components/Pagination/NavigationButton.svelte +33 -0
  65. package/dist/components/Pagination/NavigationButton.svelte.d.ts +13 -0
  66. package/dist/components/Pagination/Pagination.svelte +209 -0
  67. package/dist/components/Pagination/Pagination.svelte.d.ts +32 -0
  68. package/{components → dist/components}/Pagination/arrow-dimension.js +3 -3
  69. package/{components → dist/components}/Pagination/index.d.ts +1 -1
  70. package/dist/components/Popover.svelte +64 -0
  71. package/dist/components/Popover.svelte.d.ts +17 -0
  72. package/dist/components/Progress.svelte +87 -0
  73. package/dist/components/Progress.svelte.d.ts +19 -0
  74. package/dist/components/ScrollTop.svelte +79 -0
  75. package/dist/components/ScrollTop.svelte.d.ts +17 -0
  76. package/dist/components/Skeleton.svelte +104 -0
  77. package/dist/components/Skeleton.svelte.d.ts +21 -0
  78. package/dist/components/Spinner.svelte +59 -0
  79. package/dist/components/Spinner.svelte.d.ts +16 -0
  80. package/dist/components/Table/Table.svelte +292 -0
  81. package/dist/components/Table/Table.svelte.d.ts +25 -0
  82. package/dist/components/Table/TableColumn.svelte +62 -0
  83. package/dist/components/Table/TableColumn.svelte.d.ts +15 -0
  84. package/dist/components/Table/context.d.ts +13 -0
  85. package/dist/components/Table/context.js +1 -0
  86. package/dist/components/Table/index.d.ts +2 -0
  87. package/dist/components/Table/index.js +2 -0
  88. package/dist/components/Tabs/Tab.svelte +90 -0
  89. package/dist/components/Tabs/Tab.svelte.d.ts +14 -0
  90. package/dist/components/Tabs/Tabs.svelte +138 -0
  91. package/dist/components/Tabs/Tabs.svelte.d.ts +13 -0
  92. package/{components → dist/components}/Tabs/utils.d.ts +4 -3
  93. package/dist/components/Tag.svelte +38 -0
  94. package/dist/components/Tag.svelte.d.ts +10 -0
  95. package/dist/components/Toast/Toast.svelte +105 -0
  96. package/dist/components/Toast/Toast.svelte.d.ts +6 -0
  97. package/dist/components/Toast/ToastContainer.svelte +101 -0
  98. package/dist/components/Toast/ToastContainer.svelte.d.ts +8 -0
  99. package/{components → dist/components}/Toast/index.d.ts +19 -5
  100. package/dist/components/Toast/index.js +100 -0
  101. package/dist/icons.d.ts +3 -0
  102. package/dist/icons.js +2 -0
  103. package/dist/index.d.ts +31 -0
  104. package/{index.js → dist/index.js} +10 -5
  105. package/dist/type-icons.d.ts +4 -0
  106. package/dist/type-icons.js +9 -0
  107. package/dist/types.d.ts +29 -0
  108. package/dist/utils.d.ts +16 -0
  109. package/dist/utils.js +44 -0
  110. package/package.json +70 -68
  111. package/components/Alert.svelte +0 -34
  112. package/components/Alert.svelte.d.ts +0 -21
  113. package/components/Article.svelte +0 -39
  114. package/components/Article.svelte.d.ts +0 -26
  115. package/components/Badge.svelte +0 -16
  116. package/components/Badge.svelte.d.ts +0 -20
  117. package/components/Breadcrumb.svelte +0 -17
  118. package/components/Breadcrumb.svelte.d.ts +0 -21
  119. package/components/Button.svelte +0 -41
  120. package/components/Button.svelte.d.ts +0 -30
  121. package/components/Card.svelte +0 -70
  122. package/components/Card.svelte.d.ts +0 -32
  123. package/components/Carousel/Carousel.svelte +0 -128
  124. package/components/Carousel/Carousel.svelte.d.ts +0 -35
  125. package/components/Carousel/CarouselItem.svelte +0 -32
  126. package/components/Carousel/CarouselItem.svelte.d.ts +0 -18
  127. package/components/Carousel/types.d.ts +0 -14
  128. package/components/CloseButton.svelte +0 -23
  129. package/components/CloseButton.svelte.d.ts +0 -19
  130. package/components/Collapsible.svelte +0 -49
  131. package/components/Collapsible.svelte.d.ts +0 -21
  132. package/components/CopyButton.svelte +0 -43
  133. package/components/CopyButton.svelte.d.ts +0 -24
  134. package/components/Form/Checkbox.svelte +0 -37
  135. package/components/Form/Checkbox.svelte.d.ts +0 -26
  136. package/components/Form/Form.svelte +0 -22
  137. package/components/Form/Form.svelte.d.ts +0 -26
  138. package/components/Form/Input.svelte +0 -67
  139. package/components/Form/Input.svelte.d.ts +0 -28
  140. package/components/Form/NumberInput/DecrementButton.svelte +0 -9
  141. package/components/Form/NumberInput/DecrementButton.svelte.d.ts +0 -19
  142. package/components/Form/NumberInput/IncrementButton.svelte +0 -9
  143. package/components/Form/NumberInput/IncrementButton.svelte.d.ts +0 -19
  144. package/components/Form/NumberInput/NumberInput.svelte +0 -129
  145. package/components/Form/NumberInput/NumberInput.svelte.d.ts +0 -36
  146. package/components/Form/Radio.svelte +0 -26
  147. package/components/Form/Radio.svelte.d.ts +0 -25
  148. package/components/Form/Select.svelte +0 -40
  149. package/components/Form/Select.svelte.d.ts +0 -24
  150. package/components/Form/Slider.svelte +0 -124
  151. package/components/Form/Slider.svelte.d.ts +0 -30
  152. package/components/Form/Switch.svelte +0 -71
  153. package/components/Form/index.d.ts +0 -10
  154. package/components/Form/style.scss +0 -4
  155. package/components/Hero.svelte +0 -78
  156. package/components/Hero.svelte.d.ts +0 -26
  157. package/components/Layout/Col.svelte +0 -25
  158. package/components/Layout/Col.svelte.d.ts +0 -27
  159. package/components/Layout/Row.svelte +0 -24
  160. package/components/Layout/Row.svelte.d.ts +0 -26
  161. package/components/Layout/index.d.ts +0 -2
  162. package/components/Layout/index.js +0 -2
  163. package/components/Modal/Modal.svelte +0 -62
  164. package/components/Modal/Modal.svelte.d.ts +0 -28
  165. package/components/Modal/index.d.ts +0 -13
  166. package/components/Modal/index.js +0 -17
  167. package/components/Navbar.svelte +0 -40
  168. package/components/Navbar.svelte.d.ts +0 -22
  169. package/components/Pagination/Arrow.svelte +0 -17
  170. package/components/Pagination/Arrow.svelte.d.ts +0 -19
  171. package/components/Pagination/NavigationButton.svelte +0 -23
  172. package/components/Pagination/NavigationButton.svelte.d.ts +0 -23
  173. package/components/Pagination/Pagination.svelte +0 -137
  174. package/components/Pagination/Pagination.svelte.d.ts +0 -36
  175. package/components/Popover.svelte +0 -62
  176. package/components/Popover.svelte.d.ts +0 -25
  177. package/components/Progress.svelte +0 -39
  178. package/components/Progress.svelte.d.ts +0 -25
  179. package/components/Skeleton.svelte +0 -55
  180. package/components/Skeleton.svelte.d.ts +0 -22
  181. package/components/Table.svelte +0 -73
  182. package/components/Table.svelte.d.ts +0 -24
  183. package/components/Tabs/Tab.svelte +0 -52
  184. package/components/Tabs/Tab.svelte.d.ts +0 -20
  185. package/components/Tabs/Tabs.svelte +0 -90
  186. package/components/Tabs/Tabs.svelte.d.ts +0 -25
  187. package/components/Toast/Toast.svelte +0 -91
  188. package/components/Toast/Toast.svelte.d.ts +0 -26
  189. package/components/Toast/ToastContainer.svelte +0 -37
  190. package/components/Toast/ToastContainer.svelte.d.ts +0 -18
  191. package/components/Toast/index.js +0 -37
  192. package/index.d.ts +0 -23
  193. package/types.d.ts +0 -16
  194. package/utils.d.ts +0 -16
  195. package/utils.js +0 -34
  196. /package/{components → dist/components}/Carousel/index.js +0 -0
  197. /package/{components → dist/components}/Carousel/types.js +0 -0
  198. /package/{components → dist/components}/Form/NumberInput/index.d.ts +0 -0
  199. /package/{components → dist/components}/Form/NumberInput/index.js +0 -0
  200. /package/{components → dist/components}/Pagination/arrow-dimension.d.ts +0 -0
  201. /package/{components → dist/components}/Pagination/index.js +0 -0
  202. /package/{components → dist/components}/Tabs/index.d.ts +0 -0
  203. /package/{components → dist/components}/Tabs/index.js +0 -0
  204. /package/{components → dist/components}/Tabs/utils.js +0 -0
  205. /package/{components → dist/components}/style.scss +0 -0
  206. /package/{types.js → dist/types.js} +0 -0
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  ![version](https://img.shields.io/npm/v/spaper)
2
2
 
3
3
  # Spaper
4
- PaperCSS components for Svelte
4
+
5
+ PapierCSS components for Svelte
5
6
 
6
7
  ## Documentation
7
8
 
@@ -9,98 +10,59 @@ Browse [documentation and demo here](https://oli8.github.io/spaper/).
9
10
 
10
11
  ## Start
11
12
 
12
- ### Import papercss
13
-
14
- Add a link to the CDN into your HTML file:
15
-
16
- ```html
17
- <link rel="stylesheet" href="https://unpkg.com/papercss/dist/paper.min.css">
18
- ```
19
-
20
- Or use NPM:
13
+ ### Install
21
14
 
22
15
  ```bash
23
- npm i papercss
24
- ```
25
-
26
- then import in your main component:
27
- ```html
28
- <script>
29
- import 'papercss/dist/paper.min.css'
30
- </script>
16
+ npm i spaper papiercss tailwindcss
31
17
  ```
32
18
 
33
- ### Install spaper
19
+ ### Import papiercss
34
20
 
35
- ```bash
36
- npm i spaper
21
+ ```css
22
+ @import 'papiercss/fonts.css'; /* optional */
23
+ @import 'tailwindcss';
24
+ @import 'papiercss';
25
+ @source '../node_modules/spaper';
37
26
  ```
38
27
 
28
+ `@source` is relative to the CSS file. This scans the installed package so Tailwind generates the utility classes used inside the components.
29
+
39
30
  ### Usage
40
31
 
41
32
  ```html
42
33
  <script>
43
- import { Button } from 'spaper';
44
- // or
45
- import Alert from 'spaper/components/Alert.Svelte';
34
+ import { Button } from 'spaper'
46
35
  </script>
47
36
 
48
- <Alert>...</Alert>
49
- <Button>Click me</Button>
37
+ <button>Click me</button>
50
38
  ```
51
39
 
52
40
  <hr />
53
41
 
54
- ### Sponsors
55
-
56
- Thanks to these generous people! :heart:
57
-
58
- <table>
59
- <tr>
60
- <td align="center">
61
- <a href="https://github.com/mehdi-dalil">
62
- <img src="https://avatars.githubusercontent.com/u/65339771?v=4" width="80px;" alt=""/><br />
63
- <sub><b>mehdi-dalil</b></sub>
64
- </a>
65
- </td>
66
- <td align="center">
67
- <a href="https://github.com/t0kido">
68
- <img src="https://avatars.githubusercontent.com/u/12486500?v=4" width="80px;" alt=""/><br />
69
- <sub><b>t0kido</b></sub>
70
- </a>
71
- </td>
72
- </tr>
73
- </table>
74
-
75
-
76
42
  ### Donate
77
43
 
78
44
  Any donation is greatly appreciated :heart:
79
45
 
80
- | Source | Link / Address |
81
- | :-------------- | :------------------------------------------|
82
- | Github Sponsor | https://github.com/sponsors/Oli8 |
83
- | PayPal | https://paypal.me/OliCrt |
84
- | Bitcoin | 1Ez3Ts2WShUcbeGCjhZapdxVDK77DbYjdU |
85
- | Ethereum | 0xc4364cafac87fd8085dc26af4a4a8c3bbad1bd3e |
46
+ | Source | Link / Address |
47
+ | :------------- | :------------------------------- |
48
+ | Github Sponsor | https://github.com/sponsors/Oli8 |
49
+ | PayPal | https://paypal.me/OliCrt |
86
50
 
87
51
  #### Components
88
52
 
89
53
  - Alert
90
54
  - Article
91
- - Badge
55
+ - Tag
92
56
  - Breadcrumb
93
57
  - Button
94
58
  - Card
95
59
  - Carousel
96
60
  - CloseButton
97
- - Col
98
61
  - Collapsible
99
62
  - CopyButton
100
- - Form
101
63
  - Checkbox
102
64
  - Input
103
- - NuberInput
65
+ - NumberInput
104
66
  - Radio
105
67
  - Select
106
68
  - Slider
@@ -111,7 +73,6 @@ Any donation is greatly appreciated :heart:
111
73
  - Pagination
112
74
  - Popover
113
75
  - Progress
114
- - Row
115
76
  - Skeleton
116
77
  - Table
117
78
  - Tabs
@@ -0,0 +1,83 @@
1
+ <script lang="ts">
2
+ import { fade, slide } from 'svelte/transition'
3
+ import type { SlideParams, TransitionConfig } from 'svelte/transition'
4
+ import type { PaperType } from '../types'
5
+ import type { IconNode } from '../icons'
6
+ import { typeIcons } from '../type-icons'
7
+ import CloseButton from './CloseButton.svelte'
8
+ import Icon from './Icon.svelte'
9
+
10
+ /** outro: collapse from `slide`, opacity from `fade`. */
11
+ function slideFade(node: Element, params: SlideParams = {}): TransitionConfig {
12
+ const slideTrans = slide(node, params)
13
+ const fadeTrans = fade(node, params)
14
+ return {
15
+ delay: slideTrans.delay,
16
+ duration: slideTrans.duration,
17
+ easing: slideTrans.easing,
18
+ css: (t, u) =>
19
+ [slideTrans.css?.(t, u), fadeTrans.css?.(t, u)].filter(Boolean).join(';'),
20
+ }
21
+ }
22
+
23
+ interface Props {
24
+ type?: PaperType
25
+ /** Replaces the icon chosen from `type`. */
26
+ icon?: IconNode | null
27
+ /** Hides the icon, including the one chosen from `type`. */
28
+ hideIcon?: boolean
29
+ dismissible?: boolean
30
+ children?: import('svelte').Snippet
31
+ [key: string]: any
32
+ }
33
+
34
+ let {
35
+ type = 'primary',
36
+ icon = null,
37
+ hideIcon = false,
38
+ dismissible = false,
39
+ children,
40
+ ...rest
41
+ }: Props = $props()
42
+
43
+ const typeClass: Record<PaperType, string> = {
44
+ primary: 'alert-paper-primary',
45
+ secondary: 'alert-paper-secondary',
46
+ success: 'alert-paper-success',
47
+ warning: 'alert-paper-warning',
48
+ danger: 'alert-paper-danger',
49
+ }
50
+
51
+ let shownIcon = $derived(hideIcon ? null : (icon ?? typeIcons[type]))
52
+ let closed: boolean = $state(false)
53
+
54
+ function close(): void {
55
+ closed = true
56
+ }
57
+ </script>
58
+
59
+ {#if !closed}
60
+ <div
61
+ {...rest}
62
+ class={[
63
+ 'alert-paper',
64
+ { 'alert-paper-dismissible': dismissible },
65
+ typeClass[type],
66
+ rest.class,
67
+ ]}
68
+ role="alert"
69
+ out:slideFade={{ duration: 500 }}
70
+ >
71
+ <div class="flex items-center gap-2">
72
+ {#if shownIcon}
73
+ <Icon name={shownIcon} size={22} class="shrink-0" />
74
+ {/if}
75
+ <div>
76
+ {@render children?.()}
77
+ </div>
78
+ </div>
79
+ {#if dismissible}
80
+ <CloseButton onclick={close} />
81
+ {/if}
82
+ </div>
83
+ {/if}
@@ -0,0 +1,15 @@
1
+ import type { PaperType } from '../types';
2
+ import type { IconNode } from '../icons';
3
+ interface Props {
4
+ type?: PaperType;
5
+ /** Replaces the icon chosen from `type`. */
6
+ icon?: IconNode | null;
7
+ /** Hides the icon, including the one chosen from `type`. */
8
+ hideIcon?: boolean;
9
+ dismissible?: boolean;
10
+ children?: import('svelte').Snippet;
11
+ [key: string]: any;
12
+ }
13
+ declare const Alert: import("svelte").Component<Props, {}, "">;
14
+ type Alert = ReturnType<typeof Alert>;
15
+ export default Alert;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte'
3
+ import type { HeadingLevel, StringOrSnippet } from '../types'
4
+ import { isSnippet } from '../utils'
5
+
6
+ interface Props {
7
+ title?: StringOrSnippet
8
+ /** Heading element for the title. */
9
+ titleAs?: HeadingLevel
10
+ meta?: StringOrSnippet
11
+ textLead?: StringOrSnippet
12
+ border?: boolean
13
+ children?: Snippet
14
+ footer?: Snippet
15
+ class?: string
16
+ [key: string]: unknown
17
+ }
18
+
19
+ let {
20
+ title = '',
21
+ titleAs = 'h3',
22
+ meta = '',
23
+ textLead = '',
24
+ border = false,
25
+ children,
26
+ footer,
27
+ class: className = '',
28
+ ...rest
29
+ }: Props = $props()
30
+ </script>
31
+
32
+ <article
33
+ {...rest}
34
+ class={['article-paper', { 'border-paper': border }, className]}
35
+ >
36
+ {#if isSnippet(title) || title}
37
+ <svelte:element this={titleAs} class="article-paper-title">
38
+ {#if isSnippet(title)}{@render title()}{:else}{title}{/if}
39
+ </svelte:element>
40
+ {/if}
41
+
42
+ {#if isSnippet(meta) || meta}
43
+ <p class="article-paper-meta">
44
+ {#if isSnippet(meta)}{@render meta()}{:else}{meta}{/if}
45
+ </p>
46
+ {/if}
47
+
48
+ {#if isSnippet(textLead) || textLead}
49
+ <p class="article-paper-lead">
50
+ {#if isSnippet(textLead)}{@render textLead()}{:else}{textLead}{/if}
51
+ </p>
52
+ {/if}
53
+
54
+ {#if children}
55
+ <p>{@render children()}</p>
56
+ {/if}
57
+
58
+ {#if footer}
59
+ <footer class="flex flex-wrap">
60
+ {@render footer()}
61
+ </footer>
62
+ {/if}
63
+ </article>
@@ -0,0 +1,17 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HeadingLevel, StringOrSnippet } from '../types';
3
+ interface Props {
4
+ title?: StringOrSnippet;
5
+ /** Heading element for the title. */
6
+ titleAs?: HeadingLevel;
7
+ meta?: StringOrSnippet;
8
+ textLead?: StringOrSnippet;
9
+ border?: boolean;
10
+ children?: Snippet;
11
+ footer?: Snippet;
12
+ class?: string;
13
+ [key: string]: unknown;
14
+ }
15
+ declare const Article: import("svelte").Component<Props, {}, "">;
16
+ type Article = ReturnType<typeof Article>;
17
+ export default Article;
@@ -0,0 +1,102 @@
1
+ <script lang="ts">
2
+ import type { PaperSize, PaperColor } from '../../types'
3
+
4
+ const NAMED_SIZES = new Set<PaperSize>(['small', 'default', 'large'])
5
+
6
+ interface Props {
7
+ src?: string | null | undefined
8
+ label?: string
9
+ title?: string
10
+ type?: PaperColor
11
+ /** Size of the avatar. PapierCSS size or any CSS length. */
12
+ size?: PaperSize | string
13
+ /** Imperfect circle variant (`avatar-paper-circle-1` … `6`). */
14
+ circle?: number
15
+ children?: import('svelte').Snippet
16
+ [key: string]: any
17
+ }
18
+
19
+ let {
20
+ src = undefined,
21
+ label = '',
22
+ title = '',
23
+ type = 'primary',
24
+ size = 'default',
25
+ circle = 1,
26
+ children,
27
+ ...rest
28
+ }: Props = $props()
29
+
30
+ let failed = $state(false)
31
+ let previousSrc: string | null | undefined
32
+
33
+ $effect.pre(() => {
34
+ if (src === previousSrc) return
35
+ previousSrc = src
36
+ failed = false
37
+ })
38
+
39
+ let titleAttr = $derived(title || label)
40
+ let fallbackText = $derived(label.slice(0, 2))
41
+
42
+ const sizeClass: Record<PaperSize, string> = {
43
+ small: 'avatar-paper-sm',
44
+ default: '',
45
+ large: 'avatar-paper-lg',
46
+ }
47
+
48
+ const typeClass: Record<PaperColor, string> = {
49
+ primary: 'avatar-paper-primary',
50
+ secondary: 'avatar-paper-secondary',
51
+ success: 'avatar-paper-success',
52
+ warning: 'avatar-paper-warning',
53
+ danger: 'avatar-paper-danger',
54
+ muted: 'avatar-paper-muted',
55
+ }
56
+
57
+ let isNamedSize = $derived(
58
+ typeof size === 'string' && NAMED_SIZES.has(size as PaperSize),
59
+ )
60
+ let resolvedSizeClass = $derived(
61
+ isNamedSize ? sizeClass[size as PaperSize] : '',
62
+ )
63
+ let customSizeStyle = $derived(
64
+ !isNamedSize && size
65
+ ? `--paper-avatar-size: ${size}; --paper-avatar-font-size: calc(${size} * 0.45);`
66
+ : '',
67
+ )
68
+ const circleClasses = [
69
+ 'avatar-paper-circle-1',
70
+ 'avatar-paper-circle-2',
71
+ 'avatar-paper-circle-3',
72
+ 'avatar-paper-circle-4',
73
+ 'avatar-paper-circle-5',
74
+ 'avatar-paper-circle-6',
75
+ ]
76
+ let circleClass = $derived(circleClasses[((circle || 1) - 1) % 6])
77
+ </script>
78
+
79
+ <span
80
+ {...rest}
81
+ class={[
82
+ 'avatar-paper',
83
+ typeClass[type],
84
+ circleClass,
85
+ resolvedSizeClass,
86
+ rest.class,
87
+ ]}
88
+ style={customSizeStyle}
89
+ title={titleAttr}
90
+ aria-label={label || undefined}
91
+ >
92
+ {#if src && !failed}
93
+ <img
94
+ {src}
95
+ alt={label}
96
+ referrerpolicy="no-referrer"
97
+ onerror={() => (failed = true)}
98
+ />
99
+ {:else}
100
+ {#if children}{@render children()}{:else}{fallbackText}{/if}
101
+ {/if}
102
+ </span>
@@ -0,0 +1,16 @@
1
+ import type { PaperSize, PaperColor } from '../../types';
2
+ interface Props {
3
+ src?: string | null | undefined;
4
+ label?: string;
5
+ title?: string;
6
+ type?: PaperColor;
7
+ /** Size of the avatar. PapierCSS size or any CSS length. */
8
+ size?: PaperSize | string;
9
+ /** Imperfect circle variant (`avatar-paper-circle-1` … `6`). */
10
+ circle?: number;
11
+ children?: import('svelte').Snippet;
12
+ [key: string]: any;
13
+ }
14
+ declare const Avatar: import("svelte").Component<Props, {}, "">;
15
+ type Avatar = ReturnType<typeof Avatar>;
16
+ export default Avatar;
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { PaperSize } from '../../types'
3
+
4
+ interface Props {
5
+ size?: PaperSize
6
+ children?: import('svelte').Snippet
7
+ [key: string]: any
8
+ }
9
+
10
+ let { size = 'default', children, ...rest }: Props = $props()
11
+
12
+ const sizeClass: Record<PaperSize, string> = {
13
+ small: 'avatar-paper-stack-sm',
14
+ default: '',
15
+ large: 'avatar-paper-stack-lg',
16
+ }
17
+ </script>
18
+
19
+ <div {...rest} class={['avatar-paper-stack', sizeClass[size], rest.class]}>
20
+ {@render children?.()}
21
+ </div>
@@ -0,0 +1,9 @@
1
+ import type { PaperSize } from '../../types';
2
+ interface Props {
3
+ size?: PaperSize;
4
+ children?: import('svelte').Snippet;
5
+ [key: string]: any;
6
+ }
7
+ declare const AvatarGroup: import("svelte").Component<Props, {}, "">;
8
+ type AvatarGroup = ReturnType<typeof AvatarGroup>;
9
+ export default AvatarGroup;
@@ -0,0 +1,2 @@
1
+ export { default as Avatar } from './Avatar.svelte';
2
+ export { default as AvatarGroup } from './AvatarGroup.svelte';
@@ -0,0 +1,2 @@
1
+ export { default as Avatar } from './Avatar.svelte';
2
+ export { default as AvatarGroup } from './AvatarGroup.svelte';
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ border?: boolean
4
+ items?: { text: string; href?: string }[]
5
+ ariaLabel?: string
6
+ [key: string]: any
7
+ }
8
+
9
+ let {
10
+ border = false,
11
+ items = [],
12
+ ariaLabel = 'Breadcrumb',
13
+ ...rest
14
+ }: Props = $props()
15
+ </script>
16
+
17
+ <nav
18
+ {...rest}
19
+ class={['breadcrumb-paper', { 'border-paper': border }, rest.class]}
20
+ aria-label={ariaLabel}
21
+ >
22
+ <ol>
23
+ {#each items as { text, href }}
24
+ <li>
25
+ {#if href}
26
+ <a {href}>{text}</a>
27
+ {:else}
28
+ {text}
29
+ {/if}
30
+ </li>
31
+ {/each}
32
+ </ol>
33
+ </nav>
@@ -0,0 +1,12 @@
1
+ interface Props {
2
+ border?: boolean;
3
+ items?: {
4
+ text: string;
5
+ href?: string;
6
+ }[];
7
+ ariaLabel?: string;
8
+ [key: string]: any;
9
+ }
10
+ declare const Breadcrumb: import("svelte").Component<Props, {}, "">;
11
+ type Breadcrumb = ReturnType<typeof Breadcrumb>;
12
+ export default Breadcrumb;
@@ -0,0 +1,174 @@
1
+ <script lang="ts">
2
+ import type { Attributes, PaperSize, PaperType } from '../types'
3
+ import type { IconNode } from '../icons'
4
+ import { getDomAttributes } from '../utils'
5
+ import Icon from './Icon.svelte'
6
+ import Spinner from './Spinner.svelte'
7
+
8
+ interface Props {
9
+ type?: PaperType | null
10
+ /** Icon shown to the left of the label. */
11
+ icon?: IconNode | null
12
+ size?: PaperSize
13
+ block?: boolean
14
+ disabled?: boolean
15
+ loading?: boolean
16
+ outline?: PaperType | null
17
+ /**
18
+ * The `type` attribute for `<button>`. Useful for forms.
19
+ * Ignored if rendered as a link.
20
+ */
21
+ nativeType?: 'submit' | 'reset' | 'button' | null
22
+ /** When true, the button is rendered as an `<a>` element. */
23
+ isLink?: boolean
24
+ href?: string | null
25
+ /** When true and `isLink` is set,
26
+ * adds `target="_blank"` and `rel="noopener noreferrer"`
27
+ * to the link for external navigation.
28
+ */
29
+ external?: boolean
30
+ onclick?: (e: MouseEvent) => void
31
+ children?: import('svelte').Snippet
32
+ /** Replaces the default spinner while `loading` is set. */
33
+ loader?: import('svelte').Snippet
34
+ [key: string]: any
35
+ }
36
+
37
+ let {
38
+ type = null,
39
+ icon = null,
40
+ size = 'default',
41
+ block = false,
42
+ disabled = false,
43
+ loading = false,
44
+ outline = null,
45
+ nativeType = null,
46
+ isLink = false,
47
+ href = null,
48
+ external = false,
49
+ onclick,
50
+ children,
51
+ loader,
52
+ ...rest
53
+ }: Props = $props()
54
+
55
+ const sizeClass: Record<PaperSize, string> = {
56
+ small: 'btn-paper-sm',
57
+ default: '',
58
+ large: 'btn-paper-lg',
59
+ }
60
+
61
+ const iconSize: Record<PaperSize, number> = {
62
+ small: 16,
63
+ default: 18,
64
+ large: 28,
65
+ }
66
+
67
+ const typeClass: Record<PaperType, string> = {
68
+ primary: 'btn-paper-primary',
69
+ secondary: 'btn-paper-secondary',
70
+ success: 'btn-paper-success',
71
+ warning: 'btn-paper-warning',
72
+ danger: 'btn-paper-danger',
73
+ }
74
+
75
+ const outlineClass: Record<PaperType, string> = {
76
+ primary: 'btn-paper-primary-outline',
77
+ secondary: 'btn-paper-secondary-outline',
78
+ success: 'btn-paper-success-outline',
79
+ warning: 'btn-paper-warning-outline',
80
+ danger: 'btn-paper-danger-outline',
81
+ }
82
+
83
+ const inactive = $derived(disabled || loading)
84
+ const spinnerType = $derived(outline ?? type ?? 'secondary')
85
+ const classes = $derived([
86
+ 'btn-paper',
87
+ sizeClass[size],
88
+ { 'btn-paper-block': block },
89
+ type && typeClass[type],
90
+ outline && outlineClass[outline],
91
+ { disabled: inactive },
92
+ rest.class,
93
+ ])
94
+ const attr: Attributes = $derived(
95
+ getDomAttributes({
96
+ props: rest,
97
+ classes: '',
98
+ toOmit: ['class'],
99
+ }),
100
+ )
101
+
102
+ function handleClick(e: MouseEvent) {
103
+ if (inactive) e.preventDefault()
104
+ onclick?.(e)
105
+ }
106
+
107
+ function linkRel(rel: unknown) {
108
+ const tokens = new Set(
109
+ (typeof rel === 'string' ? rel : '').split(/\s+/).filter(Boolean),
110
+ )
111
+ tokens.add('noopener')
112
+ tokens.add('noreferrer')
113
+ return [...tokens].join(' ')
114
+ }
115
+
116
+ const anchorRel = $derived(
117
+ external
118
+ ? linkRel(attr.rel)
119
+ : typeof attr.rel === 'string'
120
+ ? attr.rel
121
+ : undefined,
122
+ )
123
+ </script>
124
+
125
+ {#snippet content()}
126
+ {#if loading || icon}
127
+ <span class="inline-flex items-center gap-2 align-middle">
128
+ {#if loading}
129
+ {#if loader}
130
+ {@render loader()}
131
+ {:else}
132
+ <Spinner
133
+ type={spinnerType}
134
+ size="small"
135
+ inline
136
+ ariaLabel=""
137
+ aria-hidden="true"
138
+ />
139
+ {/if}
140
+ {/if}
141
+ {#if icon}
142
+ <Icon name={icon} size={iconSize[size]} class="shrink-0" />
143
+ {/if}
144
+ {@render children?.()}
145
+ </span>
146
+ {:else}
147
+ {@render children?.()}
148
+ {/if}
149
+ {/snippet}
150
+
151
+ {#if isLink || href}
152
+ <a
153
+ href={href ?? undefined}
154
+ target={external ? '_blank' : undefined}
155
+ aria-busy={loading || undefined}
156
+ {...attr}
157
+ class={classes}
158
+ rel={anchorRel}
159
+ onclick={handleClick}
160
+ >
161
+ {@render content()}
162
+ </a>
163
+ {:else}
164
+ <button
165
+ {...attr}
166
+ class={classes}
167
+ type={nativeType}
168
+ disabled={inactive}
169
+ aria-busy={loading || undefined}
170
+ onclick={handleClick}
171
+ >
172
+ {@render content()}
173
+ </button>
174
+ {/if}