@startupjs-ui/tag 0.1.3

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 ADDED
@@ -0,0 +1,21 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [0.1.3](https://github.com/startupjs/startupjs-ui/compare/v0.1.2...v0.1.3) (2025-12-29)
7
+
8
+ **Note:** Version bump only for package @startupjs-ui/tag
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.1.2](https://github.com/startupjs/startupjs-ui/compare/v0.1.1...v0.1.2) (2025-12-29)
15
+
16
+
17
+ ### Features
18
+
19
+ * add mdx and docs packages. Refactor docs to get rid of any @startupjs/ui usage and use startupjs-ui instead ([703c926](https://github.com/startupjs/startupjs-ui/commit/703c92636efb0421ffd11783f692fc892b74018f))
20
+ * **menu:** refactor Menu component. Fix useColors types. ([ffd4671](https://github.com/startupjs/startupjs-ui/commit/ffd46719c308f99d856d8020ebfc070bb479ab28))
21
+ * **tag:** refactor Tag component. Add support for handling extension of Omit<> interfaces ([01f4833](https://github.com/startupjs/startupjs-ui/commit/01f483350ad61f8ecad9d11f20d7e56e3dc35952))
package/README.mdx ADDED
@@ -0,0 +1,149 @@
1
+ import { useState } from 'react'
2
+ import { faTimesCircle, faStopCircle } from '@fortawesome/free-solid-svg-icons'
3
+ import { Sandbox } from '@startupjs-ui/docs'
4
+ import Tag, { _PropsJsonSchema as TagPropsJsonSchema } from './index'
5
+ import Br from '@startupjs-ui/br'
6
+ import Div from '@startupjs-ui/div'
7
+ import './index.mdx.cssx.styl'
8
+
9
+ # Tag
10
+
11
+ Inherits [Div props](/docs/components/Div).
12
+
13
+ Tags are compact elements that represent an input, attribute, or action. They allow users to enter information, make selections, filter content, or trigger actions. While buttons are expected to appear consistently and with familiar calls to action, tags should appear dynamically as a group of multiple interactive elements.
14
+
15
+ ```js
16
+ import { Tag } from 'startupjs-ui'
17
+ ```
18
+
19
+ ## Simple example
20
+
21
+ ```jsx example
22
+ return (
23
+ <Div row>
24
+ <Tag>Tag</Tag>
25
+ </Div>
26
+ )
27
+ ```
28
+
29
+ ## Colors
30
+
31
+ Color is `primary` by default. It can be changed by passing color name from the config colors to `color` property. Possible values of property can be found in the `Sandbox` section at the bottom of the page.
32
+
33
+ ```jsx example
34
+ return (
35
+ <Div row>
36
+ <Tag>Primary (default)</Tag>
37
+ <Tag color='success' pushed='s'>Success</Tag>
38
+ <Tag color='warning' pushed='s'>Warning</Tag>
39
+ <Tag color='error' pushed='s'>Error</Tag>
40
+ </Div>
41
+ )
42
+ ```
43
+
44
+ ## Sizes
45
+
46
+ The `size` property applies to the size of tag, icons, and text. There are two sizes - `m` and` s` (default is `m`).
47
+
48
+ ```jsx example
49
+ return (
50
+ <Div style={{ alignItems: 'flex-start' }}>
51
+ <Tag size='s'>Size 's'</Tag>
52
+ <Br />
53
+ <Tag>Size 'm' (default)</Tag>
54
+ </Div>
55
+ )
56
+ ```
57
+
58
+ ## Outlined tags
59
+
60
+ Outlined tags offer an alternative style, in property `variant` need to pass `outlined` or `outlined-bg` for an outlined tag with a background.
61
+
62
+ ```jsx example
63
+ return (
64
+ <Div row>
65
+ <Tag variant='outlined'>Outlined tag</Tag>
66
+ <Tag variant='outlined-bg' pushed='s' onPress={() => {}}>Outlined tag with a background</Tag>
67
+ </Div>
68
+ )
69
+ ```
70
+
71
+ ## Shapes
72
+
73
+ Tags can have different corner shapes. It can be changed by changing `shape` prop (`circle` by default) to `rounded`.
74
+
75
+ ```jsx example
76
+ return (
77
+ <Div row>
78
+ <Tag>Circle shape</Tag>
79
+ <Tag shape='rounded' pushed='s'>Rounded shape</Tag>
80
+ </Div>
81
+ )
82
+ ```
83
+
84
+ ## Icons
85
+
86
+ Left and right icons can be added using the `icon` and `secondaryIcon` properties. To change the color of an icon, use the corresponding `iconStyleName` or `secondaryIconStyleName` property.
87
+
88
+ In `.styl` file
89
+ ```stylus
90
+ .icon
91
+ color var(--color-text-main)
92
+ .secondaryIcon
93
+ color var(--color-text-error)
94
+ ```
95
+
96
+ ```jsx example
97
+ return (
98
+ <Div row>
99
+ <Tag icon={faStopCircle}>
100
+ Icon on the left
101
+ </Tag>
102
+ <Tag
103
+ secondaryIcon={faStopCircle}
104
+ variant='outlined-bg'
105
+ pushed='s'
106
+ >
107
+ Icon on the right
108
+ </Tag>
109
+ <Tag
110
+ iconStyleName='icon'
111
+ secondaryIconStyleName='secondaryIcon'
112
+ variant='outlined'
113
+ icon={faStopCircle}
114
+ secondaryIcon={faTimesCircle}
115
+ pushed='s'
116
+ >
117
+ Two icons
118
+ </Tag>
119
+ </Div>
120
+ )
121
+ ```
122
+
123
+ ## Actions
124
+ Tag can be made interactive using `onPress` prop.
125
+
126
+ ```jsx example
127
+ const [counter, setCounter] = useState(0)
128
+ return (
129
+ <Tag onPress={() => setCounter(counter + 1)}>
130
+ Clicked {counter} times
131
+ </Tag>
132
+ )
133
+ ```
134
+
135
+ ## Sandbox
136
+
137
+ <Sandbox
138
+ Component={Tag}
139
+ propsJsonSchema={TagPropsJsonSchema}
140
+ extraParams={{
141
+ icon: { showIconSelect: true },
142
+ secondaryIcon: { showIconSelect: true }
143
+ }}
144
+ props={{
145
+ children: 'Hello world!',
146
+ onPress: () => alert('"onPress" event on Tag component'),
147
+ onLongPress: () => alert('"onLongPress" event on Tag component'),
148
+ }}
149
+ />
@@ -0,0 +1,76 @@
1
+ // ----- CONFIG: $UI.Tag
2
+
3
+ $this = merge({
4
+ heights: {
5
+ s: 2.5u,
6
+ m: 3u,
7
+ },
8
+ paddings: {
9
+ s: 1u,
10
+ m: 1.5u
11
+ },
12
+ fontSizes: {
13
+ s: 'caption',
14
+ m: 'body2'
15
+ },
16
+ iconMargins: {
17
+ inside: {
18
+ s: 0.75u,
19
+ m: 1u
20
+ }
21
+ outside: {
22
+ s: -0.25u,
23
+ m: -0.5u
24
+ }
25
+ }
26
+ outlinedBorderWidth: 1px,
27
+ disabledOpacity: 0.25
28
+ },
29
+ $UI.Tag,
30
+ true
31
+ )
32
+
33
+ .root
34
+ flex-direction row
35
+ align-items center
36
+ justify-content center
37
+
38
+ for size, height in $this.heights
39
+ &.{size}
40
+ height height
41
+
42
+ for size, padding in $this.paddings
43
+ &.{size}
44
+ padding-left padding
45
+ padding-right padding
46
+
47
+ &.disabled
48
+ opacity $this.disabledOpacity
49
+
50
+ &.outlined
51
+ &.outlined-bg
52
+ border-width: $this.outlinedBorderWidth
53
+
54
+ .label
55
+ for size, fontSize in $this.fontSizes
56
+ &.{size}
57
+ font(fontSize)
58
+
59
+ .iconWrapper
60
+ &.left
61
+ for size, margin in $this.iconMargins.inside
62
+ &.{size}
63
+ margin-right margin
64
+
65
+ for size, margin in $this.iconMargins.outside
66
+ &.{size}
67
+ margin-left margin
68
+
69
+ &.right
70
+ for size, margin in $this.iconMargins.inside
71
+ &.{size}
72
+ margin-left margin
73
+
74
+ for size, margin in $this.iconMargins.outside
75
+ &.{size}
76
+ margin-right margin
package/index.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ /* eslint-disable */
2
+ // DO NOT MODIFY THIS FILE - IT IS AUTOMATICALLY GENERATED ON COMMITS.
3
+
4
+ import { type ReactNode } from 'react';
5
+ import { type GestureResponderEvent, type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
6
+ import { type DivProps } from '@startupjs-ui/div';
7
+ import './index.cssx.styl';
8
+ declare const _default: import("react").ComponentType<TagProps>;
9
+ export default _default;
10
+ export declare const _PropsJsonSchema: {};
11
+ export interface TagProps extends Omit<DivProps, 'variant'> {
12
+ /** Custom styles applied to the root view */
13
+ style?: StyleProp<ViewStyle>;
14
+ /** Custom styles applied to the label text */
15
+ textStyle?: StyleProp<TextStyle>;
16
+ /** Tag content */
17
+ children?: ReactNode;
18
+ /** Tag color name @default 'primary' */
19
+ color?: string;
20
+ /** Tag appearance variant @default 'flat' */
21
+ variant?: 'flat' | 'outlined' | 'outlined-bg';
22
+ /** Tag size preset @default 'm' */
23
+ size?: 's' | 'm';
24
+ /** Icon displayed on the left side */
25
+ icon?: object | (() => any);
26
+ /** Custom styles applied to the left icon */
27
+ iconStyle?: StyleProp<TextStyle>;
28
+ /** Icon displayed on the right side */
29
+ secondaryIcon?: object | (() => any);
30
+ /** Custom styles applied to the right icon */
31
+ secondaryIconStyle?: StyleProp<TextStyle>;
32
+ /** Disable interactions and apply disabled styles */
33
+ disabled?: boolean;
34
+ /** Custom style for hover state */
35
+ hoverStyle?: StyleProp<ViewStyle>;
36
+ /** Custom style for active state */
37
+ activeStyle?: StyleProp<ViewStyle>;
38
+ /** Shape of the tag corners @default 'circle' */
39
+ shape?: 'circle' | 'rounded';
40
+ /** Handler for tag press */
41
+ onPress?: (event: GestureResponderEvent) => void;
42
+ /** Handler for left icon press */
43
+ onIconPress?: (event: GestureResponderEvent) => void;
44
+ /** Handler for right icon press */
45
+ onSecondaryIconPress?: (event: GestureResponderEvent) => void;
46
+ }
@@ -0,0 +1,5 @@
1
+ .icon
2
+ color var(--color-text-main)
3
+
4
+ .secondaryIcon
5
+ color var(--color-text-error)
package/index.tsx ADDED
@@ -0,0 +1,173 @@
1
+ import { type ReactNode } from 'react'
2
+ import { StyleSheet, type GestureResponderEvent, type StyleProp, type TextStyle, type ViewStyle } from 'react-native'
3
+ import { pug, observer } from 'startupjs'
4
+ import { Colors, colorToRGBA, themed, useColors } from '@startupjs-ui/core'
5
+ import Div, { type DivProps } from '@startupjs-ui/div'
6
+ import Icon from '@startupjs-ui/icon'
7
+ import Span from '@startupjs-ui/span'
8
+ import './index.cssx.styl'
9
+
10
+ const ICON_SIZES = {
11
+ s: 's',
12
+ m: 's'
13
+ }
14
+
15
+ export default observer(themed('Tag', Tag))
16
+
17
+ export const _PropsJsonSchema = {/* TagProps */}
18
+
19
+ export interface TagProps extends Omit<DivProps, 'variant'> {
20
+ /** Custom styles applied to the root view */
21
+ style?: StyleProp<ViewStyle>
22
+ /** Custom styles applied to the label text */
23
+ textStyle?: StyleProp<TextStyle>
24
+ /** Tag content */
25
+ children?: ReactNode
26
+ /** Tag color name @default 'primary' */
27
+ color?: string
28
+ /** Tag appearance variant @default 'flat' */
29
+ variant?: 'flat' | 'outlined' | 'outlined-bg'
30
+ /** Tag size preset @default 'm' */
31
+ size?: 's' | 'm'
32
+ /** Icon displayed on the left side */
33
+ icon?: object | (() => any)
34
+ /** Custom styles applied to the left icon */
35
+ iconStyle?: StyleProp<TextStyle>
36
+ /** Icon displayed on the right side */
37
+ secondaryIcon?: object | (() => any)
38
+ /** Custom styles applied to the right icon */
39
+ secondaryIconStyle?: StyleProp<TextStyle>
40
+ /** Disable interactions and apply disabled styles */
41
+ disabled?: boolean
42
+ /** Custom style for hover state */
43
+ hoverStyle?: StyleProp<ViewStyle>
44
+ /** Custom style for active state */
45
+ activeStyle?: StyleProp<ViewStyle>
46
+ /** Shape of the tag corners @default 'circle' */
47
+ shape?: 'circle' | 'rounded'
48
+ /** Handler for tag press */
49
+ onPress?: (event: GestureResponderEvent) => void
50
+ /** Handler for left icon press */
51
+ onIconPress?: (event: GestureResponderEvent) => void
52
+ /** Handler for right icon press */
53
+ onSecondaryIconPress?: (event: GestureResponderEvent) => void
54
+ }
55
+
56
+ function Tag ({
57
+ style,
58
+ textStyle,
59
+ children,
60
+ color = Colors.primary,
61
+ variant = 'flat',
62
+ size = 'm',
63
+ icon,
64
+ iconStyle,
65
+ secondaryIcon,
66
+ secondaryIconStyle,
67
+ disabled,
68
+ hoverStyle,
69
+ activeStyle,
70
+ onPress,
71
+ onIconPress,
72
+ onSecondaryIconPress,
73
+ shape = 'circle',
74
+ ...props
75
+ }: TagProps): ReactNode {
76
+ const getColor = useColors()
77
+
78
+ if (!getColor(color)) {
79
+ console.error(
80
+ 'Tag component: Color for color property is incorrect. ' +
81
+ 'Use colors from Colors'
82
+ )
83
+ }
84
+
85
+ const isFlat = variant === 'flat'
86
+ const _color = getColor(color) ?? color
87
+ const rootStyle: StyleProp<ViewStyle> = {}
88
+ let extraHoverStyle
89
+ let extraActiveStyle
90
+
91
+ textStyle = StyleSheet.flatten([
92
+ { color: isFlat ? getFlatTextColor() : _color },
93
+ textStyle
94
+ ]) as StyleProp<TextStyle>
95
+ iconStyle = StyleSheet.flatten([
96
+ { color: isFlat ? getFlatTextColor() : _color },
97
+ iconStyle
98
+ ]) as StyleProp<TextStyle>
99
+ secondaryIconStyle = StyleSheet.flatten([
100
+ { color: isFlat ? getFlatTextColor() : _color },
101
+ secondaryIconStyle
102
+ ]) as StyleProp<TextStyle>
103
+
104
+ switch (variant) {
105
+ case 'flat':
106
+ rootStyle.backgroundColor = _color
107
+ break
108
+ case 'outlined':
109
+ rootStyle.borderColor = colorToRGBA(_color, 0.5)
110
+ extraHoverStyle = { backgroundColor: colorToRGBA(_color, 0.05) }
111
+ extraActiveStyle = { backgroundColor: colorToRGBA(_color, 0.25) }
112
+ break
113
+ case 'outlined-bg':
114
+ rootStyle.borderColor = _color
115
+ rootStyle.backgroundColor = colorToRGBA(_color, 0.15)
116
+ extraHoverStyle = { backgroundColor: colorToRGBA(_color, 0.05) }
117
+ extraActiveStyle = { backgroundColor: colorToRGBA(_color, 0.25) }
118
+ break
119
+ }
120
+
121
+ function getFlatTextColor () {
122
+ return getColor(`text-on-${color}`) ?? getColor('text-on-color')
123
+ }
124
+
125
+ return pug`
126
+ Div.root(
127
+ style=[rootStyle, style]
128
+ styleName=[
129
+ variant,
130
+ size,
131
+ { disabled }
132
+ ]
133
+ variant='highlight'
134
+ hoverStyle=extraHoverStyle ? [extraHoverStyle, hoverStyle] : hoverStyle
135
+ activeStyle=extraActiveStyle ? [extraActiveStyle, activeStyle] : activeStyle
136
+ disabled=disabled
137
+ onPress=onPress
138
+ shape=shape
139
+ ...props
140
+ )
141
+ if icon
142
+ Div.iconWrapper.left(
143
+ styleName=[size]
144
+ onPress=onIconPress
145
+ )
146
+ Icon(
147
+ style=iconStyle
148
+ icon=icon
149
+ size=ICON_SIZES[size]
150
+ )
151
+
152
+ //- workaround when we interpolate variable into component
153
+ //- const value = 0
154
+ //- Tag= value
155
+ if children != null
156
+ Span.label(
157
+ style=[textStyle]
158
+ styleName=[size]
159
+ )= children
160
+
161
+ if secondaryIcon
162
+ Div.iconWrapper.right(
163
+ styleName=[size]
164
+ onPress=onSecondaryIconPress
165
+ )
166
+ Icon.icon(
167
+ style=secondaryIconStyle
168
+ styleName=[variant, size]
169
+ icon=secondaryIcon
170
+ size=ICON_SIZES[size]
171
+ )
172
+ `
173
+ }
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@startupjs-ui/tag",
3
+ "version": "0.1.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "main": "index.tsx",
8
+ "types": "index.d.ts",
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@startupjs-ui/core": "^0.1.3",
12
+ "@startupjs-ui/div": "^0.1.3",
13
+ "@startupjs-ui/icon": "^0.1.3",
14
+ "@startupjs-ui/span": "^0.1.3"
15
+ },
16
+ "peerDependencies": {
17
+ "react": "*",
18
+ "react-native": "*",
19
+ "startupjs": "*"
20
+ },
21
+ "gitHead": "fd964ebc3892d3dd0a6c85438c0af619cc50c3f0"
22
+ }