@butternutbox/pawprint-native 0.24.3 → 0.25.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@butternutbox/pawprint-native",
3
- "version": "0.24.3",
3
+ "version": "0.25.1",
4
4
  "type": "module",
5
5
  "description": "ButternutBox Pawprint Design System - React Native Components",
6
6
  "main": "./dist/index.cjs",
@@ -5,20 +5,18 @@ import type { ButtonProps } from "./Button"
5
5
  import { Typography } from "../Typography"
6
6
  import { Icon } from "../Icon"
7
7
  import {
8
- Check,
8
+ Facebook,
9
9
  IosShare,
10
10
  Whatsapp,
11
- KeyboardDoubleArrowDown
11
+ Mail
12
12
  } from "@butternutbox/pawprint-icons/core"
13
13
 
14
14
  const iconElements: Record<string, React.ReactNode> = {
15
15
  None: undefined,
16
- KeyboardDoubleArrowDown: (
17
- <Icon icon={KeyboardDoubleArrowDown} colour="primary" />
18
- ),
19
- IosShare: <Icon icon={IosShare} colour="primary" />,
20
- Whatsapp: <Icon icon={Whatsapp} colour="primary" />,
21
- Check: <Icon icon={Check} colour="primary" />
16
+ Facebook: <Icon icon={Facebook} size="sm" colour="action-default" />,
17
+ IosShare: <Icon icon={IosShare} size="sm" colour="action-default" />,
18
+ Whatsapp: <Icon icon={Whatsapp} size="sm" colour="action-default" />,
19
+ Mail: <Icon icon={Mail} size="sm" colour="action-default" />
22
20
  }
23
21
 
24
22
  const iconArgType = {
@@ -155,28 +153,104 @@ export const WithStartIcon = () => (
155
153
  <View style={styles.row}>
156
154
  <Button
157
155
  size={size}
158
- startIcon={<Icon icon={KeyboardDoubleArrowDown} colour="primary" />}
156
+ startIcon={
157
+ <Icon icon={Facebook} size="sm" colour="action-default" />
158
+ }
159
159
  >
160
- Add
160
+ Share
161
161
  </Button>
162
162
  <Button
163
163
  size={size}
164
- startIcon={<Icon icon={IosShare} colour="success" />}
164
+ startIcon={
165
+ <Icon icon={IosShare} size="sm" colour="action-default" />
166
+ }
165
167
  >
166
- Search
168
+ Export
167
169
  </Button>
168
170
  <Button
169
171
  size={size}
170
- startIcon={<Icon icon={Whatsapp} colour="warning" />}
172
+ startIcon={
173
+ <Icon icon={Whatsapp} size="sm" colour="action-default" />
174
+ }
171
175
  >
172
- Settings
176
+ Message
173
177
  </Button>
174
178
  <Button
175
179
  size={size}
176
- startIcon={<Icon icon={Check} colour="error" />}
180
+ startIcon={<Icon icon={Mail} size="sm" colour="action-default" />}
177
181
  colour="secondary"
178
182
  >
179
- Confirm
183
+ Send
184
+ </Button>
185
+ </View>
186
+ </View>
187
+ ))}
188
+ </View>
189
+ )
190
+
191
+ export const WithEndIcon = () => (
192
+ <View style={styles.column}>
193
+ {(["sm", "md", "lg"] as const).map((size) => (
194
+ <View key={size} style={styles.section}>
195
+ <Typography size="sm" weight="semiBold" color="tertiary">
196
+ {size}
197
+ </Typography>
198
+ <View style={styles.row}>
199
+ <Button
200
+ size={size}
201
+ endIcon={<Icon icon={Facebook} size="sm" colour="action-default" />}
202
+ >
203
+ Connect
204
+ </Button>
205
+ <Button
206
+ size={size}
207
+ endIcon={<Icon icon={IosShare} size="sm" colour="action-default" />}
208
+ >
209
+ Share
210
+ </Button>
211
+ <Button
212
+ size={size}
213
+ endIcon={<Icon icon={Whatsapp} size="sm" colour="action-default" />}
214
+ >
215
+ Chat
216
+ </Button>
217
+ <Button
218
+ size={size}
219
+ endIcon={<Icon icon={Mail} size="sm" colour="action-default" />}
220
+ colour="secondary"
221
+ >
222
+ Email
223
+ </Button>
224
+ </View>
225
+ </View>
226
+ ))}
227
+ </View>
228
+ )
229
+
230
+ export const WithBothIcons = () => (
231
+ <View style={styles.column}>
232
+ {(["sm", "md", "lg"] as const).map((size) => (
233
+ <View key={size} style={styles.section}>
234
+ <Typography size="sm" weight="semiBold" color="tertiary">
235
+ {size}
236
+ </Typography>
237
+ <View style={styles.row}>
238
+ <Button
239
+ size={size}
240
+ startIcon={
241
+ <Icon icon={Facebook} size="sm" colour="action-default" />
242
+ }
243
+ endIcon={<Icon icon={IosShare} size="sm" colour="action-default" />}
244
+ >
245
+ Share
246
+ </Button>
247
+ <Button
248
+ size={size}
249
+ startIcon={<Icon icon={Mail} size="sm" colour="action-default" />}
250
+ endIcon={<Icon icon={Whatsapp} size="sm" colour="action-default" />}
251
+ variant="outlined"
252
+ >
253
+ Contact
180
254
  </Button>
181
255
  </View>
182
256
  </View>
@@ -193,6 +193,17 @@ const Button = React.forwardRef<View, ButtonProps>(
193
193
 
194
194
  const variantStyles = getVariantStyles(pressed)
195
195
 
196
+ const renderIcon = (icon: React.ReactNode): React.ReactNode => {
197
+ if (!React.isValidElement(icon)) return icon
198
+ const iconElement = icon as React.ReactElement<any>
199
+ if (!pressed) {
200
+ return icon
201
+ }
202
+ return React.cloneElement(iconElement, {
203
+ customColour: variantStyles.textColor
204
+ })
205
+ }
206
+
196
207
  return (
197
208
  <StyledButton
198
209
  ref={ref}
@@ -220,7 +231,7 @@ const Button = React.forwardRef<View, ButtonProps>(
220
231
  buttonFullWidth={fullWidth}
221
232
  {...rest}
222
233
  >
223
- {startIcon && <IconWrapper>{startIcon}</IconWrapper>}
234
+ {startIcon && <IconWrapper>{renderIcon(startIcon)}</IconWrapper>}
224
235
  {/* `Typography` is a DIRECT child of the button row (no wrapping View)
225
236
  so its `<Text>` participates in flex shrink and wraps long /
226
237
  translated labels to multiple lines under the button's `minHeight`.
@@ -241,7 +252,7 @@ const Button = React.forwardRef<View, ButtonProps>(
241
252
  >
242
253
  {children}
243
254
  </Typography>
244
- {endIcon && <IconWrapper>{endIcon}</IconWrapper>}
255
+ {endIcon && <IconWrapper>{renderIcon(endIcon)}</IconWrapper>}
245
256
  {loading && (
246
257
  <StyledSpinnerWrapper>
247
258
  <Spinner
@@ -287,6 +287,45 @@ export const AllDateStates = {
287
287
  )
288
288
  }
289
289
 
290
+ export const CustomMonthLabels = {
291
+ render: () => {
292
+ const { year, month, selectedDate, setSelectedDate, prevMonth, nextMonth } =
293
+ useCalendarState()
294
+
295
+ const CUSTOM_MONTH_NAMES = [
296
+ "January",
297
+ "February",
298
+ "March",
299
+ "April",
300
+ "May",
301
+ "June",
302
+ "July",
303
+ "August",
304
+ "September",
305
+ "October",
306
+ "November",
307
+ "December"
308
+ ]
309
+
310
+ const customMonthLabel = (y: number, m: number): string =>
311
+ `${CUSTOM_MONTH_NAMES[m]} ${y}`
312
+
313
+ return (
314
+ <View style={styles.container}>
315
+ <DatePicker
316
+ year={year}
317
+ month={month}
318
+ selectedDate={selectedDate}
319
+ onDateSelect={setSelectedDate}
320
+ onPrevMonth={prevMonth}
321
+ onNextMonth={nextMonth}
322
+ getMonthLabel={customMonthLabel}
323
+ />
324
+ </View>
325
+ )
326
+ }
327
+ }
328
+
290
329
  const styles = StyleSheet.create({
291
330
  container: {
292
331
  padding: 16
@@ -118,6 +118,7 @@ type DatePickerOwnProps = {
118
118
  showNextControl?: boolean
119
119
  locale?: Locale
120
120
  monthLabel?: string
121
+ getMonthLabel?: (year: number, month: number, locale?: Locale) => string
121
122
  weekDayLabels?: [string, string, string, string, string, string, string]
122
123
  getDateState?: (date: Date) => DateItemState
123
124
  isDateDisabled?: (date: Date) => boolean
@@ -266,6 +267,7 @@ export const DatePicker = React.forwardRef<View, DatePickerProps>(
266
267
  showNextControl = true,
267
268
  locale,
268
269
  monthLabel,
270
+ getMonthLabel,
269
271
  weekDayLabels = DEFAULT_WEEK_LABELS,
270
272
  getDateState,
271
273
  isDateDisabled,
@@ -341,7 +343,9 @@ export const DatePicker = React.forwardRef<View, DatePickerProps>(
341
343
  )
342
344
 
343
345
  const resolvedMonthLabel =
344
- monthLabel ?? getDefaultMonthLabel(year, month, locale)
346
+ monthLabel ??
347
+ getMonthLabel?.(year, month, locale) ??
348
+ getDefaultMonthLabel(year, month, locale)
345
349
 
346
350
  const calendarRows = useMemo(
347
351
  () => buildCalendarGrid(year, month),
@@ -453,7 +453,10 @@ const SelectFieldRoot = React.forwardRef<View, SelectFieldProps>(
453
453
  accessibilityLabel="Search options"
454
454
  />
455
455
  ) : (
456
- <SelectFieldValue placeholder={placeholder} />
456
+ <SelectFieldValue
457
+ placeholder={placeholder}
458
+ hasValue={Boolean(currentValue)}
459
+ />
457
460
  )}
458
461
  </SelectFieldTrigger>
459
462
  {description && (
@@ -6,10 +6,11 @@ import { Typography } from "../../atoms/Typography"
6
6
 
7
7
  type SelectFieldValueProps = {
8
8
  placeholder?: string
9
+ hasValue?: boolean
9
10
  } & Omit<ViewProps, "children">
10
11
 
11
12
  export const SelectFieldValue = React.forwardRef<View, SelectFieldValueProps>(
12
- ({ placeholder, ...rest }, ref) => {
13
+ ({ placeholder, hasValue = true, ...rest }, ref) => {
13
14
  const theme = useTheme()
14
15
  const { colour, field } = theme.tokens.components.inputs
15
16
 
@@ -17,7 +18,9 @@ export const SelectFieldValue = React.forwardRef<View, SelectFieldValueProps>(
17
18
  <View ref={ref} style={{ flex: 1, minWidth: 0 }} {...rest}>
18
19
  <Typography
19
20
  token={field.placeholder.default}
20
- color={colour.field.text.default}
21
+ color={
22
+ hasValue ? colour.field.text.default : colour.field.text.placeholder
23
+ }
21
24
  align="left"
22
25
  >
23
26
  <SelectPrimitive.Value placeholder={placeholder ?? ""} />