paris 0.6.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # paris
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 5193149: Tabs: make controllable
8
+ - 2fd3be7: Drawer: bottom panel
9
+ - 8950299: Button: preset themes
10
+
3
11
  ## 0.6.0
4
12
 
5
13
  ### Minor Changes
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "paris",
3
3
  "author": "Sanil Chawla <sanil@slingshot.fm> (https://sanil.co)",
4
4
  "description": "Paris is Slingshot's React design system. It's a collection of reusable components, design tokens, and guidelines that help us build consistent, accessible, and performant user interfaces.",
5
- "version": "0.6.0",
5
+ "version": "0.6.1",
6
6
  "homepage": "https://paris.slingshot.fm",
7
7
  "license": "MIT",
8
8
  "repository": {
@@ -12,6 +12,7 @@ import styles from './Button.module.scss';
12
12
  import { Text } from '../text';
13
13
  import type { Enhancer } from '../../types/Enhancer';
14
14
  import { MemoizedEnhancer } from '../../helpers/renderEnhancer';
15
+ import { pvar } from '../theme';
15
16
 
16
17
  const EnhancerSizes = {
17
18
  large: 13,
@@ -19,6 +20,21 @@ const EnhancerSizes = {
19
20
  xs: 9,
20
21
  };
21
22
 
23
+ export const ButtonThemes = {
24
+ negative: {
25
+ primary: pvar('colors.contentNegative'),
26
+ secondary: pvar('colors.backgroundNegative'),
27
+ },
28
+ positive: {
29
+ primary: pvar('colors.contentPositive'),
30
+ secondary: pvar('colors.backgroundPositive'),
31
+ },
32
+ warning: {
33
+ primary: pvar('colors.contentWarning'),
34
+ secondary: pvar('colors.backgroundWarning'),
35
+ },
36
+ } as const;
37
+
22
38
  export type ButtonProps = {
23
39
  /**
24
40
  * The appearance of the Button.
@@ -46,6 +62,10 @@ export type ButtonProps = {
46
62
  */
47
63
  secondary: string;
48
64
  };
65
+ /**
66
+ * Preset themes for coloring the button. Overrides the `colors` prop.
67
+ */
68
+ theme?: keyof typeof ButtonThemes;
49
69
  /**
50
70
  * An icon or other element to render before the Button's text. A `size` argument is passed that should be used to determine the width & height of the content displayed.
51
71
  *
@@ -99,6 +119,7 @@ export const Button: FC<ButtonProps> = ({
99
119
  size = 'large',
100
120
  shape = 'pill',
101
121
  colors,
122
+ theme,
102
123
  type = 'button',
103
124
  startEnhancer,
104
125
  endEnhancer,
@@ -110,12 +131,12 @@ export const Button: FC<ButtonProps> = ({
110
131
  }) => (
111
132
  <AriaButton
112
133
  {...props}
113
- style={colors ? {
114
- '--pte-colors-contentInversePrimary': fontColorContrast(colors.primary),
115
- '--pte-colors-backgroundInversePrimary': colors.primary,
116
- '--pte-colors-backgroundInverseTertiary': colors.secondary,
117
- '--pte-colors-contentPrimary': colors.primary,
118
- '--pte-colors-backgroundTertiary': colors.secondary,
134
+ style={(theme || colors) ? {
135
+ '--pte-colors-contentInversePrimary': fontColorContrast(theme ? ButtonThemes[theme].primary : colors?.primary || pvar('colors.contentPrimary')),
136
+ '--pte-colors-backgroundInversePrimary': theme ? ButtonThemes[theme].primary : colors?.primary,
137
+ '--pte-colors-backgroundInverseTertiary': theme ? ButtonThemes[theme].secondary : colors?.secondary,
138
+ '--pte-colors-contentPrimary': theme ? ButtonThemes[theme].primary : colors?.primary,
139
+ '--pte-colors-backgroundTertiary': theme ? ButtonThemes[theme].secondary : colors?.secondary,
119
140
  } as CSSProperties : {}}
120
141
  className={clsx(
121
142
  styles.button,
@@ -330,3 +330,8 @@ $panelAnimationDelay: var(--pte-animations-duration-fast);
330
330
  .paginationLeave {
331
331
  transition: $paginationDuration var(--pte-animations-timing-easeOutQuad);
332
332
  }
333
+
334
+ .bottomPanel {
335
+ padding: 20px;
336
+ border-top: 1px solid var(--pte-colors-borderOpaque);
337
+ }
@@ -60,6 +60,10 @@ export type DrawerProps<T extends string[] | readonly string[] = string[]> = {
60
60
  * @default false
61
61
  */
62
62
  hideCloseButton?: boolean;
63
+ /**
64
+ * An optional panel that will be rendered at the bottom of the Drawer. This is useful for adding a footer to the Drawer with actions.
65
+ */
66
+ bottomPanel?: ReactNode;
63
67
  /**
64
68
  * The direction from which the Drawer will appear.
65
69
  */
@@ -120,6 +124,7 @@ export const Drawer = <T extends string[] | readonly string[] = string[]>({
120
124
  title,
121
125
  hideTitle = false,
122
126
  hideCloseButton = false,
127
+ bottomPanel,
123
128
  from = 'right',
124
129
  size = 'default',
125
130
  pagination,
@@ -341,6 +346,12 @@ export const Drawer = <T extends string[] | readonly string[] = string[]>({
341
346
  </Transition>
342
347
  )) : children}
343
348
  </div>
349
+
350
+ <RemoveFromDOM when={!bottomPanel}>
351
+ <div className={styles.bottomPanel}>
352
+ {bottomPanel}
353
+ </div>
354
+ </RemoveFromDOM>
344
355
  </Dialog.Panel>
345
356
  </Transition.Child>
346
357
  </div>
@@ -34,6 +34,10 @@ export type TabsProps = {
34
34
  * The default index of the tab to render. Defaults to `0`.
35
35
  */
36
36
  defaultIndex?: number;
37
+ /**
38
+ * Pass in a controlled index to control the selected tab.
39
+ */
40
+ index?: number;
37
41
  /**
38
42
  * An optional handler for tab changes.
39
43
  * @param index - The index of the tab that was selected.
@@ -58,6 +62,7 @@ export const Tabs: FC<TabsProps> = ({
58
62
  tabWidth = '150px',
59
63
  kind = 'auto',
60
64
  defaultIndex = 0,
65
+ index,
61
66
  onTabChange,
62
67
  }) => {
63
68
  const id = useId();
@@ -66,7 +71,7 @@ export const Tabs: FC<TabsProps> = ({
66
71
  return (
67
72
  <Tab.Group
68
73
  as="div"
69
- selectedIndex={selectedIndex}
74
+ selectedIndex={index ?? selectedIndex}
70
75
  onChange={(i) => {
71
76
  setSelectedIndex(i);
72
77
  if (onTabChange) {
@@ -77,13 +82,13 @@ export const Tabs: FC<TabsProps> = ({
77
82
  <Tab.List
78
83
  style={{
79
84
  '--tab-width': tabWidth,
80
- '--tab-index': `${selectedIndex}`,
85
+ '--tab-index': `${index ?? selectedIndex}`,
81
86
  } as CSSProperties}
82
87
  className={clsx(
83
88
  styles.tabList,
84
89
  )}
85
90
  >
86
- {tabs.map(({ title }, index) => (
91
+ {tabs.map(({ title }, i) => (
87
92
  <Tab
88
93
  key={`${id}-tab-${title}`}
89
94
  className={clsx(
@@ -93,7 +98,7 @@ export const Tabs: FC<TabsProps> = ({
93
98
  )}
94
99
  >
95
100
  {title}
96
- {index === selectedIndex && (
101
+ {i === (index ?? selectedIndex) && (
97
102
  <motion.div
98
103
  key={`${id}-tab-active-border`}
99
104
  className={styles.activeTabUnderline}