mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 02:15:05 +03:00
Merge pull request #9039 from supabase/feat/migrate-supabase-ui
Feat - migrate supabase UI. Move studio to turborepo
This commit is contained in:
1130 files changed
+32572
-14537
No files matched your search
@@ -195,6 +195,15 @@ The monorepo has a set of shared components under `/packages`:
|
||||
- `/packages/config`: All shared config
|
||||
- `/packages/spec`: Generates documentation using spec files.
|
||||
- `/packages/tsconfig`: Shared Typescript settings
|
||||
- `/packages/ui`: Shared UI components (formerly @supabase/ui)
|
||||
|
||||
To use these 'packages', or any of their components from a Next.JS app, you must use `next-transpile-modules` in the `next.config.js` file. This looks like:
|
||||
|
||||
```tsx
|
||||
// next.config.js
|
||||
const withTM = require('next-transpile-modules')(['ui', 'common'])
|
||||
module.exports = withTM({})
|
||||
```
|
||||
|
||||
### Installing packages
|
||||
|
||||
|
||||
Generated
+4322
-13141
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,221 @@
|
||||
const deepMerge = require('deepmerge')
|
||||
const customFormsPlugin = require('@tailwindcss/forms')
|
||||
|
||||
const colors = {
|
||||
transparent: 'transparent',
|
||||
white: '#ffffff',
|
||||
black: '#000000',
|
||||
gray: {
|
||||
'50': '#f9fafb',
|
||||
'100': '#f4f5f7',
|
||||
'200': '#e5e7eb',
|
||||
'300': '#d5d6d7',
|
||||
'400': '#9e9e9e',
|
||||
'500': '#707275',
|
||||
'600': '#4c4f52',
|
||||
'700': '#24262d',
|
||||
'800': '#1a1c23',
|
||||
'900': '#121317',
|
||||
// default values from Tailwind UI palette
|
||||
// '300': '#d2d6dc',
|
||||
// '400': '#9fa6b2',
|
||||
// '500': '#6b7280',
|
||||
// '600': '#4b5563',
|
||||
// '700': '#374151',
|
||||
// '800': '#252f3f',
|
||||
// '900': '#161e2e',
|
||||
},
|
||||
'cool-gray': {
|
||||
'50': '#fbfdfe',
|
||||
'100': '#f1f5f9',
|
||||
'200': '#e2e8f0',
|
||||
'300': '#cfd8e3',
|
||||
'400': '#97a6ba',
|
||||
'500': '#64748b',
|
||||
'600': '#475569',
|
||||
'700': '#364152',
|
||||
'800': '#27303f',
|
||||
'900': '#1a202e',
|
||||
},
|
||||
red: {
|
||||
'50': '#fdf2f2',
|
||||
'100': '#fde8e8',
|
||||
'200': '#fbd5d5',
|
||||
'300': '#f8b4b4',
|
||||
'400': '#f98080',
|
||||
'500': '#f05252',
|
||||
'600': '#e02424',
|
||||
'700': '#c81e1e',
|
||||
'800': '#9b1c1c',
|
||||
'900': '#771d1d',
|
||||
},
|
||||
orange: {
|
||||
'50': '#fff8f1',
|
||||
'100': '#feecdc',
|
||||
'200': '#fcd9bd',
|
||||
'300': '#fdba8c',
|
||||
'400': '#ff8a4c',
|
||||
'500': '#ff5a1f',
|
||||
'600': '#d03801',
|
||||
'700': '#b43403',
|
||||
'800': '#8a2c0d',
|
||||
'900': '#771d1d',
|
||||
},
|
||||
yellow: {
|
||||
'50': '#fdfdea',
|
||||
'100': '#fdf6b2',
|
||||
'200': '#fce96a',
|
||||
'300': '#faca15',
|
||||
'400': '#e3a008',
|
||||
'500': '#c27803',
|
||||
'600': '#9f580a',
|
||||
'700': '#8e4b10',
|
||||
'800': '#723b13',
|
||||
'900': '#633112',
|
||||
},
|
||||
green: {
|
||||
'50': '#f3faf7',
|
||||
'100': '#def7ec',
|
||||
'200': '#bcf0da',
|
||||
'300': '#84e1bc',
|
||||
'400': '#31c48d',
|
||||
'500': '#0e9f6e',
|
||||
'600': '#057a55',
|
||||
'700': '#046c4e',
|
||||
'800': '#03543f',
|
||||
'900': '#014737',
|
||||
},
|
||||
teal: {
|
||||
'50': '#edfafa',
|
||||
'100': '#d5f5f6',
|
||||
'200': '#afecef',
|
||||
'300': '#7edce2',
|
||||
'400': '#16bdca',
|
||||
'500': '#0694a2',
|
||||
'600': '#047481',
|
||||
'700': '#036672',
|
||||
'800': '#05505c',
|
||||
'900': '#014451',
|
||||
},
|
||||
blue: {
|
||||
'50': '#ebf5ff',
|
||||
'100': '#e1effe',
|
||||
'200': '#c3ddfd',
|
||||
'300': '#a4cafe',
|
||||
'400': '#76a9fa',
|
||||
'500': '#3f83f8',
|
||||
'600': '#1c64f2',
|
||||
'700': '#1a56db',
|
||||
'800': '#1e429f',
|
||||
'900': '#233876',
|
||||
},
|
||||
indigo: {
|
||||
'50': '#f0f5ff',
|
||||
'100': '#e5edff',
|
||||
'200': '#cddbfe',
|
||||
'300': '#b4c6fc',
|
||||
'400': '#8da2fb',
|
||||
'500': '#6875f5',
|
||||
'600': '#5850ec',
|
||||
'700': '#5145cd',
|
||||
'800': '#42389d',
|
||||
'900': '#362f78',
|
||||
},
|
||||
purple: {
|
||||
'50': '#f6f5ff',
|
||||
'100': '#edebfe',
|
||||
'200': '#dcd7fe',
|
||||
'300': '#cabffd',
|
||||
'400': '#ac94fa',
|
||||
'500': '#9061f9',
|
||||
'600': '#7e3af2',
|
||||
'700': '#6c2bd9',
|
||||
'800': '#5521b5',
|
||||
'900': '#4a1d96',
|
||||
},
|
||||
pink: {
|
||||
'50': '#fdf2f8',
|
||||
'100': '#fce8f3',
|
||||
'200': '#fad1e8',
|
||||
'300': '#f8b4d9',
|
||||
'400': '#f17eb8',
|
||||
'500': '#e74694',
|
||||
'600': '#d61f69',
|
||||
'700': '#bf125d',
|
||||
'800': '#99154b',
|
||||
'900': '#751a3d',
|
||||
},
|
||||
}
|
||||
|
||||
const backgroundOpacity = (theme) => ({
|
||||
'10': '0.1',
|
||||
...theme('opacity'),
|
||||
})
|
||||
|
||||
const maxHeight = (theme) => ({
|
||||
'0': '0',
|
||||
xl: '36rem',
|
||||
...theme('spacing'),
|
||||
})
|
||||
|
||||
const windmillConfig = {
|
||||
darkMode: 'class',
|
||||
purge: {
|
||||
content: [
|
||||
'node_modules/@supabase/ui/theme/defaultTheme.js',
|
||||
// 'node_modules/@supabase/ui/dist/index.js',
|
||||
],
|
||||
},
|
||||
theme: {
|
||||
colors,
|
||||
backgroundOpacity,
|
||||
maxHeight,
|
||||
},
|
||||
variants: {
|
||||
backgroundOpacity: ['responsive', 'hover', 'focus', 'dark'],
|
||||
backgroundColor: ['responsive', 'hover', 'focus', 'active', 'odd', 'dark'],
|
||||
display: ['responsive', 'dark'],
|
||||
textColor: [
|
||||
'responsive',
|
||||
'focus',
|
||||
'focus-within',
|
||||
'hover',
|
||||
'active',
|
||||
'dark',
|
||||
],
|
||||
placeholderColor: ['responsive', 'focus', 'dark'],
|
||||
borderColor: ['responsive', 'hover', 'focus', 'dark'],
|
||||
divideColor: ['responsive', 'dark'],
|
||||
boxShadow: ['responsive', 'hover', 'focus', 'dark'],
|
||||
margin: ['responsive', 'last'],
|
||||
},
|
||||
plugins: [customFormsPlugin],
|
||||
}
|
||||
|
||||
function arrayMergeFn(destinationArray, sourceArray) {
|
||||
return destinationArray.concat(sourceArray).reduce((acc, cur) => {
|
||||
if (acc.includes(cur)) return acc
|
||||
return [...acc, cur]
|
||||
}, [])
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge Windmill and Tailwind CSS configurations
|
||||
* @param {object} tailwindConfig - Tailwind config object
|
||||
* @return {object} new config object
|
||||
*/
|
||||
export function wrapper(tailwindConfig) {
|
||||
let purge
|
||||
if (Array.isArray(tailwindConfig.purge)) {
|
||||
purge = {
|
||||
content: tailwindConfig.purge,
|
||||
}
|
||||
} else {
|
||||
purge = tailwindConfig.purge
|
||||
}
|
||||
return deepMerge({ ...tailwindConfig, purge }, windmillConfig, {
|
||||
arrayMerge: arrayMergeFn,
|
||||
})
|
||||
}
|
||||
|
||||
// module.exports = wrapper
|
||||
@@ -0,0 +1,90 @@
|
||||
module.exports = {
|
||||
brand: {
|
||||
brand1: 'hsla(153, 80%, 99%, 1)',
|
||||
brand2: 'hsla(148, 88%, 97%, 1)',
|
||||
brand3: 'hsla(148, 76%, 95%, 1)',
|
||||
brand4: 'hsla(148, 68%, 92%, 1)',
|
||||
brand5: 'hsla(148, 59%, 88%, 1)',
|
||||
brand6: 'hsla(149, 43%, 82%, 1)',
|
||||
brand7: 'hsla(149, 43%, 69%, 1)',
|
||||
brand8: 'hsla(154, 55%, 45%, 1)',
|
||||
brand9: 'hsla(153, 60%, 53%, 1)',
|
||||
brand10: 'hsla(153, 50%, 50%, 1)',
|
||||
brand11: 'hsla(153, 50%, 34%, 1)',
|
||||
brand12: 'hsla(153, 40%, 12%, 1)',
|
||||
},
|
||||
brandDark: {
|
||||
brand1: 'hsla(153, 75%, 6%, 1)',
|
||||
brand2: 'hsla(153, 73%, 7%, 1)',
|
||||
brand3: 'hsla(154, 69%, 9%, 1)',
|
||||
brand4: 'hsla(154, 67%, 11%, 1)',
|
||||
brand5: 'hsla(154, 66%, 13%, 1)',
|
||||
brand6: 'hsla(154, 64%, 17%, 1)',
|
||||
brand7: 'hsla(154, 62%, 22%, 1)',
|
||||
brand8: 'hsla(153, 60%, 28%, 1)',
|
||||
brand9: 'hsla(153, 60%, 53%, 1)',
|
||||
brand10: 'hsla(153, 60%, 70%, 1)',
|
||||
brand11: 'hsla(153, 60%, 50%, 1)',
|
||||
brand12: 'hsla(153, 60%, 95%, 1)',
|
||||
},
|
||||
contrast: {
|
||||
'brand-hiContrast': 'var(--colors-brand-9)',
|
||||
'brand-loContrast': 'var(--colors-brand-4)',
|
||||
},
|
||||
scale: {
|
||||
scale1: 'var(--colors-slate1)',
|
||||
scale2: 'var(--colors-slate2)',
|
||||
scale3: 'var(--colors-slate3)',
|
||||
scale4: 'var(--colors-slate4)',
|
||||
scale5: 'var(--colors-slate5)',
|
||||
scale6: 'var(--colors-slate6)',
|
||||
scale7: 'var(--colors-slate7)',
|
||||
scale8: 'var(--colors-slate8)',
|
||||
scale9: 'var(--colors-slate9)',
|
||||
scale10: 'var(--colors-slate10)',
|
||||
scale11: 'var(--colors-slate11)',
|
||||
scale12: 'var(--colors-slate12)',
|
||||
},
|
||||
scaleA: {
|
||||
scaleA1: 'var(--colors-slatea1)',
|
||||
scaleA2: 'var(--colors-slatea2)',
|
||||
scaleA3: 'var(--colors-slatea3)',
|
||||
scaleA4: 'var(--colors-slatea4)',
|
||||
scaleA5: 'var(--colors-slatea5)',
|
||||
scaleA6: 'var(--colors-slatea6)',
|
||||
scaleA7: 'var(--colors-slatea7)',
|
||||
scaleA8: 'var(--colors-slatea8)',
|
||||
scaleA9: 'var(--colors-slatea9)',
|
||||
scaleA10: 'var(--colors-slatea10)',
|
||||
scaleA11: 'var(--colors-slatea11)',
|
||||
scaleA12: 'var(--colors-slatea12)',
|
||||
},
|
||||
scaleDark: {
|
||||
scale1: 'var(--colors-gray1)',
|
||||
scale2: 'var(--colors-gray2)',
|
||||
scale3: 'var(--colors-gray3)',
|
||||
scale4: 'var(--colors-gray4)',
|
||||
scale5: 'var(--colors-gray5)',
|
||||
scale6: 'var(--colors-gray6)',
|
||||
scale7: 'var(--colors-gray7)',
|
||||
scale8: 'var(--colors-gray8)',
|
||||
scale9: 'var(--colors-gray9)',
|
||||
scale10: 'var(--colors-gray10)',
|
||||
scale11: 'var(--colors-gray11)',
|
||||
scale12: 'var(--colors-gray12)',
|
||||
},
|
||||
scaleADark: {
|
||||
scaleA1: 'var(--colors-graya1)',
|
||||
scaleA2: 'var(--colors-graya2)',
|
||||
scaleA3: 'var(--colors-graya3)',
|
||||
scaleA4: 'var(--colors-graya4)',
|
||||
scaleA5: 'var(--colors-graya5)',
|
||||
scaleA6: 'var(--colors-graya6)',
|
||||
scaleA7: 'var(--colors-graya7)',
|
||||
scaleA8: 'var(--colors-graya8)',
|
||||
scaleA9: 'var(--colors-graya9)',
|
||||
scaleA10: 'var(--colors-graya10)',
|
||||
scaleA11: 'var(--colors-graya11)',
|
||||
scaleA12: 'var(--colors-graya12)',
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
import * as React from 'react'
|
||||
|
||||
// // GENERAL
|
||||
|
||||
export * from './src/components/Button'
|
||||
export * from './src/components/Icon'
|
||||
export * from './src/components/Icon/IconContext'
|
||||
// export * from './src/components/Image'
|
||||
|
||||
// DISPLAYS
|
||||
|
||||
export * from './src/components/Card'
|
||||
export * from './src/components/Badge'
|
||||
export * from './src/components/Tabs'
|
||||
export * from './src/components/Alert'
|
||||
export * from './src/components/Accordion'
|
||||
export * from './src/components/Collapsible'
|
||||
// export * from './src/components/Breadcrumb'
|
||||
|
||||
// NAV
|
||||
|
||||
export * from './src/components/Menu'
|
||||
|
||||
// OVERLAYS
|
||||
|
||||
export * from './src/components/Modal'
|
||||
export * from './src/components/SidePanel'
|
||||
export * from './src/components/Dropdown'
|
||||
export * from './src/components/ContextMenu'
|
||||
export * from './src/components/Popover'
|
||||
// export * from './src/components/Toast'
|
||||
|
||||
// UTILITIES
|
||||
|
||||
export * from './src/components/Space'
|
||||
export * from './src/components/Loading'
|
||||
export * from './src/components/Divider'
|
||||
export * from './src/components/ThemeProvider'
|
||||
|
||||
// DATA ENTRY
|
||||
|
||||
export * from './src/components/Select'
|
||||
export * from './src/components/Listbox'
|
||||
export * from './src/components/Checkbox'
|
||||
export * from './src/components/Input'
|
||||
export * from './src/components/InputNumber'
|
||||
export * from './src/components/Radio'
|
||||
export * from './src/components/Toggle'
|
||||
export * from './src/components/Upload'
|
||||
export * from './src/components/Form'
|
||||
|
||||
// config
|
||||
|
||||
// export { default as Config } from './../ui.config'
|
||||
|
||||
// ARCHIVE
|
||||
|
||||
// export * from './src/components/Textarea'
|
||||
|
||||
// AUTH
|
||||
|
||||
// export * from './src/components/Auth'
|
||||
|
||||
// ICONS
|
||||
|
||||
// export icons
|
||||
export * from './src/components/Icon/icons/IconActivity'
|
||||
export * from './src/components/Icon/icons/IconAirplay'
|
||||
export * from './src/components/Icon/icons/IconAlertCircle'
|
||||
export * from './src/components/Icon/icons/IconAlertOctagon'
|
||||
export * from './src/components/Icon/icons/IconAlertTriangle'
|
||||
export * from './src/components/Icon/icons/IconAlignCenter'
|
||||
export * from './src/components/Icon/icons/IconAlignJustify'
|
||||
export * from './src/components/Icon/icons/IconAlignLeft'
|
||||
export * from './src/components/Icon/icons/IconAlignRight'
|
||||
export * from './src/components/Icon/icons/IconAnchor'
|
||||
export * from './src/components/Icon/icons/IconAperture'
|
||||
export * from './src/components/Icon/icons/IconArchive'
|
||||
export * from './src/components/Icon/icons/IconArrowDownCircle'
|
||||
export * from './src/components/Icon/icons/IconArrowDownLeft'
|
||||
export * from './src/components/Icon/icons/IconArrowDownRight'
|
||||
export * from './src/components/Icon/icons/IconArrowDown'
|
||||
export * from './src/components/Icon/icons/IconArrowLeftCircle'
|
||||
export * from './src/components/Icon/icons/IconArrowLeft'
|
||||
export * from './src/components/Icon/icons/IconArrowRightCircle'
|
||||
export * from './src/components/Icon/icons/IconArrowRight'
|
||||
export * from './src/components/Icon/icons/IconArrowUpCircle'
|
||||
export * from './src/components/Icon/icons/IconArrowUpLeft'
|
||||
export * from './src/components/Icon/icons/IconArrowUpRight'
|
||||
export * from './src/components/Icon/icons/IconArrowUp'
|
||||
export * from './src/components/Icon/icons/IconAtSign'
|
||||
export * from './src/components/Icon/icons/IconAward'
|
||||
export * from './src/components/Icon/icons/IconBarChart2'
|
||||
export * from './src/components/Icon/icons/IconBarChart'
|
||||
export * from './src/components/Icon/icons/IconBatteryCharging'
|
||||
export * from './src/components/Icon/icons/IconBattery'
|
||||
export * from './src/components/Icon/icons/IconBellOff'
|
||||
export * from './src/components/Icon/icons/IconBell'
|
||||
export * from './src/components/Icon/icons/IconBluetooth'
|
||||
export * from './src/components/Icon/icons/IconBold'
|
||||
export * from './src/components/Icon/icons/IconBookOpen'
|
||||
export * from './src/components/Icon/icons/IconBook'
|
||||
export * from './src/components/Icon/icons/IconBookmark'
|
||||
export * from './src/components/Icon/icons/IconBox'
|
||||
export * from './src/components/Icon/icons/IconBriefcase'
|
||||
export * from './src/components/Icon/icons/IconCalendar'
|
||||
export * from './src/components/Icon/icons/IconCameraOff'
|
||||
export * from './src/components/Icon/icons/IconCamera'
|
||||
export * from './src/components/Icon/icons/IconCast'
|
||||
export * from './src/components/Icon/icons/IconCheckCircle'
|
||||
export * from './src/components/Icon/icons/IconCheckSquare'
|
||||
export * from './src/components/Icon/icons/IconCheck'
|
||||
export * from './src/components/Icon/icons/IconChevronDown'
|
||||
export * from './src/components/Icon/icons/IconChevronLeft'
|
||||
export * from './src/components/Icon/icons/IconChevronRight'
|
||||
export * from './src/components/Icon/icons/IconChevronUp'
|
||||
export * from './src/components/Icon/icons/IconChevronsDown'
|
||||
export * from './src/components/Icon/icons/IconChevronsLeft'
|
||||
export * from './src/components/Icon/icons/IconChevronsRight'
|
||||
export * from './src/components/Icon/icons/IconChevronsUp'
|
||||
export * from './src/components/Icon/icons/IconChrome'
|
||||
export * from './src/components/Icon/icons/IconCircle'
|
||||
export * from './src/components/Icon/icons/IconClipboard'
|
||||
export * from './src/components/Icon/icons/IconClock'
|
||||
export * from './src/components/Icon/icons/IconCloudDrizzle'
|
||||
export * from './src/components/Icon/icons/IconCloudLightning'
|
||||
export * from './src/components/Icon/icons/IconCloudOff'
|
||||
export * from './src/components/Icon/icons/IconCloudRain'
|
||||
export * from './src/components/Icon/icons/IconCloudSnow'
|
||||
export * from './src/components/Icon/icons/IconCloud'
|
||||
export * from './src/components/Icon/icons/IconCode'
|
||||
export * from './src/components/Icon/icons/IconCodepen'
|
||||
export * from './src/components/Icon/icons/IconCodesandbox'
|
||||
export * from './src/components/Icon/icons/IconCoffee'
|
||||
export * from './src/components/Icon/icons/IconColumns'
|
||||
export * from './src/components/Icon/icons/IconCommand'
|
||||
export * from './src/components/Icon/icons/IconCompass'
|
||||
export * from './src/components/Icon/icons/IconCopy'
|
||||
export * from './src/components/Icon/icons/IconCornerDownLeft'
|
||||
export * from './src/components/Icon/icons/IconCornerDownRight'
|
||||
export * from './src/components/Icon/icons/IconCornerLeftDown'
|
||||
export * from './src/components/Icon/icons/IconCornerLeftUp'
|
||||
export * from './src/components/Icon/icons/IconCornerRightDown'
|
||||
export * from './src/components/Icon/icons/IconCornerRightUp'
|
||||
export * from './src/components/Icon/icons/IconCornerUpLeft'
|
||||
export * from './src/components/Icon/icons/IconCornerUpRight'
|
||||
export * from './src/components/Icon/icons/IconCpu'
|
||||
export * from './src/components/Icon/icons/IconCreditCard'
|
||||
export * from './src/components/Icon/icons/IconCrop'
|
||||
export * from './src/components/Icon/icons/IconCrosshair'
|
||||
export * from './src/components/Icon/icons/IconDatabase'
|
||||
export * from './src/components/Icon/icons/IconDelete'
|
||||
export * from './src/components/Icon/icons/IconDisc'
|
||||
export * from './src/components/Icon/icons/IconDivideCircle'
|
||||
export * from './src/components/Icon/icons/IconDivideSquare'
|
||||
export * from './src/components/Icon/icons/IconDivide'
|
||||
export * from './src/components/Icon/icons/IconDollarSign'
|
||||
export * from './src/components/Icon/icons/IconDownloadCloud'
|
||||
export * from './src/components/Icon/icons/IconDownload'
|
||||
export * from './src/components/Icon/icons/IconDribbble'
|
||||
export * from './src/components/Icon/icons/IconDroplet'
|
||||
export * from './src/components/Icon/icons/IconEdit2'
|
||||
export * from './src/components/Icon/icons/IconEdit3'
|
||||
export * from './src/components/Icon/icons/IconEdit'
|
||||
export * from './src/components/Icon/icons/IconExternalLink'
|
||||
export * from './src/components/Icon/icons/IconEyeOff'
|
||||
export * from './src/components/Icon/icons/IconEye'
|
||||
export * from './src/components/Icon/icons/IconFacebook'
|
||||
export * from './src/components/Icon/icons/IconFastForward'
|
||||
export * from './src/components/Icon/icons/IconFeather'
|
||||
export * from './src/components/Icon/icons/IconFigma'
|
||||
export * from './src/components/Icon/icons/IconFileMinus'
|
||||
export * from './src/components/Icon/icons/IconFilePlus'
|
||||
export * from './src/components/Icon/icons/IconFileText'
|
||||
export * from './src/components/Icon/icons/IconFile'
|
||||
export * from './src/components/Icon/icons/IconFilm'
|
||||
export * from './src/components/Icon/icons/IconFilter'
|
||||
export * from './src/components/Icon/icons/IconFlag'
|
||||
export * from './src/components/Icon/icons/IconFolderMinus'
|
||||
export * from './src/components/Icon/icons/IconFolderPlus'
|
||||
export * from './src/components/Icon/icons/IconFolder'
|
||||
export * from './src/components/Icon/icons/IconFramer'
|
||||
export * from './src/components/Icon/icons/IconFrown'
|
||||
export * from './src/components/Icon/icons/IconGift'
|
||||
export * from './src/components/Icon/icons/IconGitBranch'
|
||||
export * from './src/components/Icon/icons/IconGitCommit'
|
||||
export * from './src/components/Icon/icons/IconGitMerge'
|
||||
export * from './src/components/Icon/icons/IconGitPullRequest'
|
||||
export * from './src/components/Icon/icons/IconGitHub'
|
||||
export * from './src/components/Icon/icons/IconGitlab'
|
||||
export * from './src/components/Icon/icons/IconGlobe'
|
||||
export * from './src/components/Icon/icons/IconGrid'
|
||||
export * from './src/components/Icon/icons/IconHardDrive'
|
||||
export * from './src/components/Icon/icons/IconHash'
|
||||
export * from './src/components/Icon/icons/IconHeadphones'
|
||||
export * from './src/components/Icon/icons/IconHeart'
|
||||
export * from './src/components/Icon/icons/IconHelpCircle'
|
||||
export * from './src/components/Icon/icons/IconHexagon'
|
||||
export * from './src/components/Icon/icons/IconHome'
|
||||
export * from './src/components/Icon/icons/IconImage'
|
||||
export * from './src/components/Icon/icons/IconInbox'
|
||||
export * from './src/components/Icon/icons/IconInfo'
|
||||
export * from './src/components/Icon/icons/IconInstagram'
|
||||
export * from './src/components/Icon/icons/IconItalic'
|
||||
export * from './src/components/Icon/icons/IconKey'
|
||||
export * from './src/components/Icon/icons/IconLayers'
|
||||
export * from './src/components/Icon/icons/IconLayout'
|
||||
export * from './src/components/Icon/icons/IconLifeBuoy'
|
||||
export * from './src/components/Icon/icons/IconLink2'
|
||||
export * from './src/components/Icon/icons/IconLink'
|
||||
export * from './src/components/Icon/icons/IconLinkedin'
|
||||
export * from './src/components/Icon/icons/IconList'
|
||||
export * from './src/components/Icon/icons/IconLoader'
|
||||
export * from './src/components/Icon/icons/IconLock'
|
||||
export * from './src/components/Icon/icons/IconLogIn'
|
||||
export * from './src/components/Icon/icons/IconLogOut'
|
||||
export * from './src/components/Icon/icons/IconMail'
|
||||
export * from './src/components/Icon/icons/IconMapPin'
|
||||
export * from './src/components/Icon/icons/IconMap'
|
||||
export * from './src/components/Icon/icons/IconMaximize2'
|
||||
export * from './src/components/Icon/icons/IconMaximize'
|
||||
export * from './src/components/Icon/icons/IconMeh'
|
||||
export * from './src/components/Icon/icons/IconMenu'
|
||||
export * from './src/components/Icon/icons/IconMessageCircle'
|
||||
export * from './src/components/Icon/icons/IconMessageSquare'
|
||||
export * from './src/components/Icon/icons/IconMicOff'
|
||||
export * from './src/components/Icon/icons/IconMic'
|
||||
export * from './src/components/Icon/icons/IconMinimize2'
|
||||
export * from './src/components/Icon/icons/IconMinimize'
|
||||
export * from './src/components/Icon/icons/IconMinusCircle'
|
||||
export * from './src/components/Icon/icons/IconMinusSquare'
|
||||
export * from './src/components/Icon/icons/IconMinus'
|
||||
export * from './src/components/Icon/icons/IconMonitor'
|
||||
export * from './src/components/Icon/icons/IconMoon'
|
||||
export * from './src/components/Icon/icons/IconMoreHorizontal'
|
||||
export * from './src/components/Icon/icons/IconMoreVertical'
|
||||
export * from './src/components/Icon/icons/IconMousePointer'
|
||||
export * from './src/components/Icon/icons/IconMove'
|
||||
export * from './src/components/Icon/icons/IconMusic'
|
||||
export * from './src/components/Icon/icons/IconNavigation2'
|
||||
export * from './src/components/Icon/icons/IconNavigation'
|
||||
export * from './src/components/Icon/icons/IconOctagon'
|
||||
export * from './src/components/Icon/icons/IconPackage'
|
||||
export * from './src/components/Icon/icons/IconPaperclip'
|
||||
export * from './src/components/Icon/icons/IconPauseCircle'
|
||||
export * from './src/components/Icon/icons/IconPause'
|
||||
export * from './src/components/Icon/icons/IconPenTool'
|
||||
export * from './src/components/Icon/icons/IconPercent'
|
||||
export * from './src/components/Icon/icons/IconPhoneCall'
|
||||
export * from './src/components/Icon/icons/IconPhoneForwarded'
|
||||
export * from './src/components/Icon/icons/IconPhoneIncoming'
|
||||
export * from './src/components/Icon/icons/IconPhoneMissed'
|
||||
export * from './src/components/Icon/icons/IconPhoneOff'
|
||||
export * from './src/components/Icon/icons/IconPhoneOutgoing'
|
||||
export * from './src/components/Icon/icons/IconPhone'
|
||||
export * from './src/components/Icon/icons/IconPieChart'
|
||||
export * from './src/components/Icon/icons/IconPlayCircle'
|
||||
export * from './src/components/Icon/icons/IconPlay'
|
||||
export * from './src/components/Icon/icons/IconPlusCircle'
|
||||
export * from './src/components/Icon/icons/IconPlusSquare'
|
||||
export * from './src/components/Icon/icons/IconPlus'
|
||||
export * from './src/components/Icon/icons/IconPocket'
|
||||
export * from './src/components/Icon/icons/IconPower'
|
||||
export * from './src/components/Icon/icons/IconPrinter'
|
||||
export * from './src/components/Icon/icons/IconRadio'
|
||||
export * from './src/components/Icon/icons/IconRefreshCcw'
|
||||
export * from './src/components/Icon/icons/IconRefreshCw'
|
||||
export * from './src/components/Icon/icons/IconRepeat'
|
||||
export * from './src/components/Icon/icons/IconRewind'
|
||||
export * from './src/components/Icon/icons/IconRotateCcw'
|
||||
export * from './src/components/Icon/icons/IconRotateCw'
|
||||
export * from './src/components/Icon/icons/IconRss'
|
||||
export * from './src/components/Icon/icons/IconSave'
|
||||
export * from './src/components/Icon/icons/IconScissors'
|
||||
export * from './src/components/Icon/icons/IconSearch'
|
||||
export * from './src/components/Icon/icons/IconSend'
|
||||
export * from './src/components/Icon/icons/IconServer'
|
||||
export * from './src/components/Icon/icons/IconSettings'
|
||||
export * from './src/components/Icon/icons/IconShare2'
|
||||
export * from './src/components/Icon/icons/IconShare'
|
||||
export * from './src/components/Icon/icons/IconShieldOff'
|
||||
export * from './src/components/Icon/icons/IconShield'
|
||||
export * from './src/components/Icon/icons/IconShoppingBag'
|
||||
export * from './src/components/Icon/icons/IconShoppingCart'
|
||||
export * from './src/components/Icon/icons/IconShuffle'
|
||||
export * from './src/components/Icon/icons/IconSidebar'
|
||||
export * from './src/components/Icon/icons/IconSkipBack'
|
||||
export * from './src/components/Icon/icons/IconSkipForward'
|
||||
export * from './src/components/Icon/icons/IconSlack'
|
||||
export * from './src/components/Icon/icons/IconSlash'
|
||||
export * from './src/components/Icon/icons/IconSliders'
|
||||
export * from './src/components/Icon/icons/IconSmartphone'
|
||||
export * from './src/components/Icon/icons/IconSmile'
|
||||
export * from './src/components/Icon/icons/IconSpeaker'
|
||||
export * from './src/components/Icon/icons/IconSquare'
|
||||
export * from './src/components/Icon/icons/IconStar'
|
||||
export * from './src/components/Icon/icons/IconStopCircle'
|
||||
export * from './src/components/Icon/icons/IconSun'
|
||||
export * from './src/components/Icon/icons/IconSunrise'
|
||||
export * from './src/components/Icon/icons/IconSunset'
|
||||
export * from './src/components/Icon/icons/IconTablet'
|
||||
export * from './src/components/Icon/icons/IconTag'
|
||||
export * from './src/components/Icon/icons/IconTarget'
|
||||
export * from './src/components/Icon/icons/IconTerminal'
|
||||
export * from './src/components/Icon/icons/IconThermometer'
|
||||
export * from './src/components/Icon/icons/IconThumbsDown'
|
||||
export * from './src/components/Icon/icons/IconThumbsUp'
|
||||
export * from './src/components/Icon/icons/IconToggleLeft'
|
||||
export * from './src/components/Icon/icons/IconToggleRight'
|
||||
export * from './src/components/Icon/icons/IconTool'
|
||||
export * from './src/components/Icon/icons/IconTrash2'
|
||||
export * from './src/components/Icon/icons/IconTrash'
|
||||
export * from './src/components/Icon/icons/IconTrello'
|
||||
export * from './src/components/Icon/icons/IconTrendingDown'
|
||||
export * from './src/components/Icon/icons/IconTrendingUp'
|
||||
export * from './src/components/Icon/icons/IconTriangle'
|
||||
export * from './src/components/Icon/icons/IconTruck'
|
||||
export * from './src/components/Icon/icons/IconTv'
|
||||
export * from './src/components/Icon/icons/IconTwitch'
|
||||
export * from './src/components/Icon/icons/IconTwitter'
|
||||
export * from './src/components/Icon/icons/IconType'
|
||||
export * from './src/components/Icon/icons/IconUmbrella'
|
||||
export * from './src/components/Icon/icons/IconUnderline'
|
||||
export * from './src/components/Icon/icons/IconUnlock'
|
||||
export * from './src/components/Icon/icons/IconUploadCloud'
|
||||
export * from './src/components/Icon/icons/IconUpload'
|
||||
export * from './src/components/Icon/icons/IconUserCheck'
|
||||
export * from './src/components/Icon/icons/IconUserMinus'
|
||||
export * from './src/components/Icon/icons/IconUserPlus'
|
||||
export * from './src/components/Icon/icons/IconUserX'
|
||||
export * from './src/components/Icon/icons/IconUser'
|
||||
export * from './src/components/Icon/icons/IconUsers'
|
||||
export * from './src/components/Icon/icons/IconVideoOff'
|
||||
export * from './src/components/Icon/icons/IconVideo'
|
||||
export * from './src/components/Icon/icons/IconVoicemail'
|
||||
export * from './src/components/Icon/icons/IconVolume1'
|
||||
export * from './src/components/Icon/icons/IconVolume2'
|
||||
export * from './src/components/Icon/icons/IconVolumeX'
|
||||
export * from './src/components/Icon/icons/IconVolume'
|
||||
export * from './src/components/Icon/icons/IconWatch'
|
||||
export * from './src/components/Icon/icons/IconWifiOff'
|
||||
export * from './src/components/Icon/icons/IconWifi'
|
||||
export * from './src/components/Icon/icons/IconWind'
|
||||
export * from './src/components/Icon/icons/IconXCircle'
|
||||
export * from './src/components/Icon/icons/IconXOctagon'
|
||||
export * from './src/components/Icon/icons/IconXSquare'
|
||||
export * from './src/components/Icon/icons/IconX'
|
||||
export * from './src/components/Icon/icons/IconYoutube'
|
||||
export * from './src/components/Icon/icons/IconZapOff'
|
||||
export * from './src/components/Icon/icons/IconZap'
|
||||
export * from './src/components/Icon/icons/IconZoomIn'
|
||||
export * from './src/components/Icon/icons/IconZoomOut'
|
||||
@@ -0,0 +1,288 @@
|
||||
export default {
|
||||
IconActivity: 'src/components/Icon/icons/IconActivity/index.tsx',
|
||||
IconAirplay: 'src/components/Icon/icons/IconAirplay/index.tsx',
|
||||
IconAlertCircle: 'src/components/Icon/icons/IconAlertCircle/index.tsx',
|
||||
IconAlertOctagon: 'src/components/Icon/icons/IconAlertOctagon/index.tsx',
|
||||
IconAlertTriangle: 'src/components/Icon/icons/IconAlertTriangle/index.tsx',
|
||||
IconAlignCenter: 'src/components/Icon/icons/IconAlignCenter/index.tsx',
|
||||
IconAlignJustify: 'src/components/Icon/icons/IconAlignJustify/index.tsx',
|
||||
IconAlignLeft: 'src/components/Icon/icons/IconAlignLeft/index.tsx',
|
||||
IconAlignRight: 'src/components/Icon/icons/IconAlignRight/index.tsx',
|
||||
IconAnchor: 'src/components/Icon/icons/IconAnchor/index.tsx',
|
||||
IconAperture: 'src/components/Icon/icons/IconAperture/index.tsx',
|
||||
IconArchive: 'src/components/Icon/icons/IconArchive/index.tsx',
|
||||
IconArrowDownCircle: 'src/components/Icon/icons/IconArrowDownCircle/index.tsx',
|
||||
IconArrowDownLeft: 'src/components/Icon/icons/IconArrowDownLeft/index.tsx',
|
||||
IconArrowDownRight: 'src/components/Icon/icons/IconArrowDownRight/index.tsx',
|
||||
IconArrowDown: 'src/components/Icon/icons/IconArrowDown/index.tsx',
|
||||
IconArrowLeftCircle: 'src/components/Icon/icons/IconArrowLeftCircle/index.tsx',
|
||||
IconArrowLeft: 'src/components/Icon/icons/IconArrowLeft/index.tsx',
|
||||
IconArrowRightCircle: 'src/components/Icon/icons/IconArrowRightCircle/index.tsx',
|
||||
IconArrowRight: 'src/components/Icon/icons/IconArrowRight/index.tsx',
|
||||
IconArrowUpCircle: 'src/components/Icon/icons/IconArrowUpCircle/index.tsx',
|
||||
IconArrowUpLeft: 'src/components/Icon/icons/IconArrowUpLeft/index.tsx',
|
||||
IconArrowUpRight: 'src/components/Icon/icons/IconArrowUpRight/index.tsx',
|
||||
IconArrowUp: 'src/components/Icon/icons/IconArrowUp/index.tsx',
|
||||
IconAtSign: 'src/components/Icon/icons/IconAtSign/index.tsx',
|
||||
IconAward: 'src/components/Icon/icons/IconAward/index.tsx',
|
||||
IconBarChart2: 'src/components/Icon/icons/IconBarChart2/index.tsx',
|
||||
IconBarChart: 'src/components/Icon/icons/IconBarChart/index.tsx',
|
||||
IconBatteryCharging: 'src/components/Icon/icons/IconBatteryCharging/index.tsx',
|
||||
IconBattery: 'src/components/Icon/icons/IconBattery/index.tsx',
|
||||
IconBellOff: 'src/components/Icon/icons/IconBellOff/index.tsx',
|
||||
IconBell: 'src/components/Icon/icons/IconBell/index.tsx',
|
||||
IconBluetooth: 'src/components/Icon/icons/IconBluetooth/index.tsx',
|
||||
IconBold: 'src/components/Icon/icons/IconBold/index.tsx',
|
||||
IconBookOpen: 'src/components/Icon/icons/IconBookOpen/index.tsx',
|
||||
IconBook: 'src/components/Icon/icons/IconBook/index.tsx',
|
||||
IconBookmark: 'src/components/Icon/icons/IconBookmark/index.tsx',
|
||||
IconBox: 'src/components/Icon/icons/IconBox/index.tsx',
|
||||
IconBriefcase: 'src/components/Icon/icons/IconBriefcase/index.tsx',
|
||||
IconCalendar: 'src/components/Icon/icons/IconCalendar/index.tsx',
|
||||
IconCameraOff: 'src/components/Icon/icons/IconCameraOff/index.tsx',
|
||||
IconCamera: 'src/components/Icon/icons/IconCamera/index.tsx',
|
||||
IconCast: 'src/components/Icon/icons/IconCast/index.tsx',
|
||||
IconCheckCircle: 'src/components/Icon/icons/IconCheckCircle/index.tsx',
|
||||
IconCheckSquare: 'src/components/Icon/icons/IconCheckSquare/index.tsx',
|
||||
IconCheck: 'src/components/Icon/icons/IconCheck/index.tsx',
|
||||
IconChevronDown: 'src/components/Icon/icons/IconChevronDown/index.tsx',
|
||||
IconChevronLeft: 'src/components/Icon/icons/IconChevronLeft/index.tsx',
|
||||
IconChevronRight: 'src/components/Icon/icons/IconChevronRight/index.tsx',
|
||||
IconChevronUp: 'src/components/Icon/icons/IconChevronUp/index.tsx',
|
||||
IconChevronsDown: 'src/components/Icon/icons/IconChevronsDown/index.tsx',
|
||||
IconChevronsLeft: 'src/components/Icon/icons/IconChevronsLeft/index.tsx',
|
||||
IconChevronsRight: 'src/components/Icon/icons/IconChevronsRight/index.tsx',
|
||||
IconChevronsUp: 'src/components/Icon/icons/IconChevronsUp/index.tsx',
|
||||
IconChrome: 'src/components/Icon/icons/IconChrome/index.tsx',
|
||||
IconCircle: 'src/components/Icon/icons/IconCircle/index.tsx',
|
||||
IconClipboard: 'src/components/Icon/icons/IconClipboard/index.tsx',
|
||||
IconClock: 'src/components/Icon/icons/IconClock/index.tsx',
|
||||
IconCloudDrizzle: 'src/components/Icon/icons/IconCloudDrizzle/index.tsx',
|
||||
IconCloudLightning: 'src/components/Icon/icons/IconCloudLightning/index.tsx',
|
||||
IconCloudOff: 'src/components/Icon/icons/IconCloudOff/index.tsx',
|
||||
IconCloudRain: 'src/components/Icon/icons/IconCloudRain/index.tsx',
|
||||
IconCloudSnow: 'src/components/Icon/icons/IconCloudSnow/index.tsx',
|
||||
IconCloud: 'src/components/Icon/icons/IconCloud/index.tsx',
|
||||
IconCode: 'src/components/Icon/icons/IconCode/index.tsx',
|
||||
IconCodepen: 'src/components/Icon/icons/IconCodepen/index.tsx',
|
||||
IconCodesandbox: 'src/components/Icon/icons/IconCodesandbox/index.tsx',
|
||||
IconCoffee: 'src/components/Icon/icons/IconCoffee/index.tsx',
|
||||
IconColumns: 'src/components/Icon/icons/IconColumns/index.tsx',
|
||||
IconCommand: 'src/components/Icon/icons/IconCommand/index.tsx',
|
||||
IconCompass: 'src/components/Icon/icons/IconCompass/index.tsx',
|
||||
IconCopy: 'src/components/Icon/icons/IconCopy/index.tsx',
|
||||
IconCornerDownLeft: 'src/components/Icon/icons/IconCornerDownLeft/index.tsx',
|
||||
IconCornerDownRight: 'src/components/Icon/icons/IconCornerDownRight/index.tsx',
|
||||
IconCornerLeftDown: 'src/components/Icon/icons/IconCornerLeftDown/index.tsx',
|
||||
IconCornerLeftUp: 'src/components/Icon/icons/IconCornerLeftUp/index.tsx',
|
||||
IconCornerRightDown: 'src/components/Icon/icons/IconCornerRightDown/index.tsx',
|
||||
IconCornerRightUp: 'src/components/Icon/icons/IconCornerRightUp/index.tsx',
|
||||
IconCornerUpLeft: 'src/components/Icon/icons/IconCornerUpLeft/index.tsx',
|
||||
IconCornerUpRight: 'src/components/Icon/icons/IconCornerUpRight/index.tsx',
|
||||
IconCpu: 'src/components/Icon/icons/IconCpu/index.tsx',
|
||||
IconCreditCard: 'src/components/Icon/icons/IconCreditCard/index.tsx',
|
||||
IconCrop: 'src/components/Icon/icons/IconCrop/index.tsx',
|
||||
IconCrosshair: 'src/components/Icon/icons/IconCrosshair/index.tsx',
|
||||
IconDatabase: 'src/components/Icon/icons/IconDatabase/index.tsx',
|
||||
IconDelete: 'src/components/Icon/icons/IconDelete/index.tsx',
|
||||
IconDisc: 'src/components/Icon/icons/IconDisc/index.tsx',
|
||||
IconDivideCircle: 'src/components/Icon/icons/IconDivideCircle/index.tsx',
|
||||
IconDivideSquare: 'src/components/Icon/icons/IconDivideSquare/index.tsx',
|
||||
IconDivide: 'src/components/Icon/icons/IconDivide/index.tsx',
|
||||
IconDollarSign: 'src/components/Icon/icons/IconDollarSign/index.tsx',
|
||||
IconDownloadCloud: 'src/components/Icon/icons/IconDownloadCloud/index.tsx',
|
||||
IconDownload: 'src/components/Icon/icons/IconDownload/index.tsx',
|
||||
IconDribbble: 'src/components/Icon/icons/IconDribbble/index.tsx',
|
||||
IconDroplet: 'src/components/Icon/icons/IconDroplet/index.tsx',
|
||||
IconEdit2: 'src/components/Icon/icons/IconEdit2/index.tsx',
|
||||
IconEdit3: 'src/components/Icon/icons/IconEdit3/index.tsx',
|
||||
IconEdit: 'src/components/Icon/icons/IconEdit/index.tsx',
|
||||
IconExternalLink: 'src/components/Icon/icons/IconExternalLink/index.tsx',
|
||||
IconEyeOff: 'src/components/Icon/icons/IconEyeOff/index.tsx',
|
||||
IconEye: 'src/components/Icon/icons/IconEye/index.tsx',
|
||||
IconFacebook: 'src/components/Icon/icons/IconFacebook/index.tsx',
|
||||
IconFastForward: 'src/components/Icon/icons/IconFastForward/index.tsx',
|
||||
IconFeather: 'src/components/Icon/icons/IconFeather/index.tsx',
|
||||
IconFigma: 'src/components/Icon/icons/IconFigma/index.tsx',
|
||||
IconFileMinus: 'src/components/Icon/icons/IconFileMinus/index.tsx',
|
||||
IconFilePlus: 'src/components/Icon/icons/IconFilePlus/index.tsx',
|
||||
IconFileText: 'src/components/Icon/icons/IconFileText/index.tsx',
|
||||
IconFile: 'src/components/Icon/icons/IconFile/index.tsx',
|
||||
IconFilm: 'src/components/Icon/icons/IconFilm/index.tsx',
|
||||
IconFilter: 'src/components/Icon/icons/IconFilter/index.tsx',
|
||||
IconFlag: 'src/components/Icon/icons/IconFlag/index.tsx',
|
||||
IconFolderMinus: 'src/components/Icon/icons/IconFolderMinus/index.tsx',
|
||||
IconFolderPlus: 'src/components/Icon/icons/IconFolderPlus/index.tsx',
|
||||
IconFolder: 'src/components/Icon/icons/IconFolder/index.tsx',
|
||||
IconFramer: 'src/components/Icon/icons/IconFramer/index.tsx',
|
||||
IconFrown: 'src/components/Icon/icons/IconFrown/index.tsx',
|
||||
IconGift: 'src/components/Icon/icons/IconGift/index.tsx',
|
||||
IconGitBranch: 'src/components/Icon/icons/IconGitBranch/index.tsx',
|
||||
IconGitCommit: 'src/components/Icon/icons/IconGitCommit/index.tsx',
|
||||
IconGitMerge: 'src/components/Icon/icons/IconGitMerge/index.tsx',
|
||||
IconGitPullRequest: 'src/components/Icon/icons/IconGitPullRequest/index.tsx',
|
||||
IconGitHub: 'src/components/Icon/icons/IconGitHub/index.tsx',
|
||||
IconGitlab: 'src/components/Icon/icons/IconGitlab/index.tsx',
|
||||
IconGlobe: 'src/components/Icon/icons/IconGlobe/index.tsx',
|
||||
IconGrid: 'src/components/Icon/icons/IconGrid/index.tsx',
|
||||
IconHardDrive: 'src/components/Icon/icons/IconHardDrive/index.tsx',
|
||||
IconHash: 'src/components/Icon/icons/IconHash/index.tsx',
|
||||
IconHeadphones: 'src/components/Icon/icons/IconHeadphones/index.tsx',
|
||||
IconHeart: 'src/components/Icon/icons/IconHeart/index.tsx',
|
||||
IconHelpCircle: 'src/components/Icon/icons/IconHelpCircle/index.tsx',
|
||||
IconHexagon: 'src/components/Icon/icons/IconHexagon/index.tsx',
|
||||
IconHome: 'src/components/Icon/icons/IconHome/index.tsx',
|
||||
IconImage: 'src/components/Icon/icons/IconImage/index.tsx',
|
||||
IconInbox: 'src/components/Icon/icons/IconInbox/index.tsx',
|
||||
IconInfo: 'src/components/Icon/icons/IconInfo/index.tsx',
|
||||
IconInstagram: 'src/components/Icon/icons/IconInstagram/index.tsx',
|
||||
IconItalic: 'src/components/Icon/icons/IconItalic/index.tsx',
|
||||
IconKey: 'src/components/Icon/icons/IconKey/index.tsx',
|
||||
IconLayers: 'src/components/Icon/icons/IconLayers/index.tsx',
|
||||
IconLayout: 'src/components/Icon/icons/IconLayout/index.tsx',
|
||||
IconLifeBuoy: 'src/components/Icon/icons/IconLifeBuoy/index.tsx',
|
||||
IconLink2: 'src/components/Icon/icons/IconLink2/index.tsx',
|
||||
IconLink: 'src/components/Icon/icons/IconLink/index.tsx',
|
||||
IconLinkedin: 'src/components/Icon/icons/IconLinkedin/index.tsx',
|
||||
IconList: 'src/components/Icon/icons/IconList/index.tsx',
|
||||
IconLoader: 'src/components/Icon/icons/IconLoader/index.tsx',
|
||||
IconLock: 'src/components/Icon/icons/IconLock/index.tsx',
|
||||
IconLogIn: 'src/components/Icon/icons/IconLogIn/index.tsx',
|
||||
IconLogOut: 'src/components/Icon/icons/IconLogOut/index.tsx',
|
||||
IconMail: 'src/components/Icon/icons/IconMail/index.tsx',
|
||||
IconMapPin: 'src/components/Icon/icons/IconMapPin/index.tsx',
|
||||
IconMap: 'src/components/Icon/icons/IconMap/index.tsx',
|
||||
IconMaximize2: 'src/components/Icon/icons/IconMaximize2/index.tsx',
|
||||
IconMaximize: 'src/components/Icon/icons/IconMaximize/index.tsx',
|
||||
IconMeh: 'src/components/Icon/icons/IconMeh/index.tsx',
|
||||
IconMenu: 'src/components/Icon/icons/IconMenu/index.tsx',
|
||||
IconMessageCircle: 'src/components/Icon/icons/IconMessageCircle/index.tsx',
|
||||
IconMessageSquare: 'src/components/Icon/icons/IconMessageSquare/index.tsx',
|
||||
IconMicOff: 'src/components/Icon/icons/IconMicOff/index.tsx',
|
||||
IconMic: 'src/components/Icon/icons/IconMic/index.tsx',
|
||||
IconMinimize2: 'src/components/Icon/icons/IconMinimize2/index.tsx',
|
||||
IconMinimize: 'src/components/Icon/icons/IconMinimize/index.tsx',
|
||||
IconMinusCircle: 'src/components/Icon/icons/IconMinusCircle/index.tsx',
|
||||
IconMinusSquare: 'src/components/Icon/icons/IconMinusSquare/index.tsx',
|
||||
IconMinus: 'src/components/Icon/icons/IconMinus/index.tsx',
|
||||
IconMonitor: 'src/components/Icon/icons/IconMonitor/index.tsx',
|
||||
IconMoon: 'src/components/Icon/icons/IconMoon/index.tsx',
|
||||
IconMoreHorizontal: 'src/components/Icon/icons/IconMoreHorizontal/index.tsx',
|
||||
IconMoreVertical: 'src/components/Icon/icons/IconMoreVertical/index.tsx',
|
||||
IconMousePointer: 'src/components/Icon/icons/IconMousePointer/index.tsx',
|
||||
IconMove: 'src/components/Icon/icons/IconMove/index.tsx',
|
||||
IconMusic: 'src/components/Icon/icons/IconMusic/index.tsx',
|
||||
IconNavigation2: 'src/components/Icon/icons/IconNavigation2/index.tsx',
|
||||
IconNavigation: 'src/components/Icon/icons/IconNavigation/index.tsx',
|
||||
IconOctagon: 'src/components/Icon/icons/IconOctagon/index.tsx',
|
||||
IconPackage: 'src/components/Icon/icons/IconPackage/index.tsx',
|
||||
IconPaperclip: 'src/components/Icon/icons/IconPaperclip/index.tsx',
|
||||
IconPauseCircle: 'src/components/Icon/icons/IconPauseCircle/index.tsx',
|
||||
IconPause: 'src/components/Icon/icons/IconPause/index.tsx',
|
||||
IconPenTool: 'src/components/Icon/icons/IconPenTool/index.tsx',
|
||||
IconPercent: 'src/components/Icon/icons/IconPercent/index.tsx',
|
||||
IconPhoneCall: 'src/components/Icon/icons/IconPhoneCall/index.tsx',
|
||||
IconPhoneForwarded: 'src/components/Icon/icons/IconPhoneForwarded/index.tsx',
|
||||
IconPhoneIncoming: 'src/components/Icon/icons/IconPhoneIncoming/index.tsx',
|
||||
IconPhoneMissed: 'src/components/Icon/icons/IconPhoneMissed/index.tsx',
|
||||
IconPhoneOff: 'src/components/Icon/icons/IconPhoneOff/index.tsx',
|
||||
IconPhoneOutgoing: 'src/components/Icon/icons/IconPhoneOutgoing/index.tsx',
|
||||
IconPhone: 'src/components/Icon/icons/IconPhone/index.tsx',
|
||||
IconPieChart: 'src/components/Icon/icons/IconPieChart/index.tsx',
|
||||
IconPlayCircle: 'src/components/Icon/icons/IconPlayCircle/index.tsx',
|
||||
IconPlay: 'src/components/Icon/icons/IconPlay/index.tsx',
|
||||
IconPlusCircle: 'src/components/Icon/icons/IconPlusCircle/index.tsx',
|
||||
IconPlusSquare: 'src/components/Icon/icons/IconPlusSquare/index.tsx',
|
||||
IconPlus: 'src/components/Icon/icons/IconPlus/index.tsx',
|
||||
IconPocket: 'src/components/Icon/icons/IconPocket/index.tsx',
|
||||
IconPower: 'src/components/Icon/icons/IconPower/index.tsx',
|
||||
IconPrinter: 'src/components/Icon/icons/IconPrinter/index.tsx',
|
||||
IconRadio: 'src/components/Icon/icons/IconRadio/index.tsx',
|
||||
IconRefreshCcw: 'src/components/Icon/icons/IconRefreshCcw/index.tsx',
|
||||
IconRefreshCw: 'src/components/Icon/icons/IconRefreshCw/index.tsx',
|
||||
IconRepeat: 'src/components/Icon/icons/IconRepeat/index.tsx',
|
||||
IconRewind: 'src/components/Icon/icons/IconRewind/index.tsx',
|
||||
IconRotateCcw: 'src/components/Icon/icons/IconRotateCcw/index.tsx',
|
||||
IconRotateCw: 'src/components/Icon/icons/IconRotateCw/index.tsx',
|
||||
IconRss: 'src/components/Icon/icons/IconRss/index.tsx',
|
||||
IconSave: 'src/components/Icon/icons/IconSave/index.tsx',
|
||||
IconScissors: 'src/components/Icon/icons/IconScissors/index.tsx',
|
||||
IconSearch: 'src/components/Icon/icons/IconSearch/index.tsx',
|
||||
IconSend: 'src/components/Icon/icons/IconSend/index.tsx',
|
||||
IconServer: 'src/components/Icon/icons/IconServer/index.tsx',
|
||||
IconSettings: 'src/components/Icon/icons/IconSettings/index.tsx',
|
||||
IconShare2: 'src/components/Icon/icons/IconShare2/index.tsx',
|
||||
IconShare: 'src/components/Icon/icons/IconShare/index.tsx',
|
||||
IconShieldOff: 'src/components/Icon/icons/IconShieldOff/index.tsx',
|
||||
IconShield: 'src/components/Icon/icons/IconShield/index.tsx',
|
||||
IconShoppingBag: 'src/components/Icon/icons/IconShoppingBag/index.tsx',
|
||||
IconShoppingCart: 'src/components/Icon/icons/IconShoppingCart/index.tsx',
|
||||
IconShuffle: 'src/components/Icon/icons/IconShuffle/index.tsx',
|
||||
IconSidebar: 'src/components/Icon/icons/IconSidebar/index.tsx',
|
||||
IconSkipBack: 'src/components/Icon/icons/IconSkipBack/index.tsx',
|
||||
IconSkipForward: 'src/components/Icon/icons/IconSkipForward/index.tsx',
|
||||
IconSlack: 'src/components/Icon/icons/IconSlack/index.tsx',
|
||||
IconSlash: 'src/components/Icon/icons/IconSlash/index.tsx',
|
||||
IconSliders: 'src/components/Icon/icons/IconSliders/index.tsx',
|
||||
IconSmartphone: 'src/components/Icon/icons/IconSmartphone/index.tsx',
|
||||
IconSmile: 'src/components/Icon/icons/IconSmile/index.tsx',
|
||||
IconSpeaker: 'src/components/Icon/icons/IconSpeaker/index.tsx',
|
||||
IconSquare: 'src/components/Icon/icons/IconSquare/index.tsx',
|
||||
IconStar: 'src/components/Icon/icons/IconStar/index.tsx',
|
||||
IconStopCircle: 'src/components/Icon/icons/IconStopCircle/index.tsx',
|
||||
IconSun: 'src/components/Icon/icons/IconSun/index.tsx',
|
||||
IconSunrise: 'src/components/Icon/icons/IconSunrise/index.tsx',
|
||||
IconSunset: 'src/components/Icon/icons/IconSunset/index.tsx',
|
||||
IconTablet: 'src/components/Icon/icons/IconTablet/index.tsx',
|
||||
IconTag: 'src/components/Icon/icons/IconTag/index.tsx',
|
||||
IconTarget: 'src/components/Icon/icons/IconTarget/index.tsx',
|
||||
IconTerminal: 'src/components/Icon/icons/IconTerminal/index.tsx',
|
||||
IconThermometer: 'src/components/Icon/icons/IconThermometer/index.tsx',
|
||||
IconThumbsDown: 'src/components/Icon/icons/IconThumbsDown/index.tsx',
|
||||
IconThumbsUp: 'src/components/Icon/icons/IconThumbsUp/index.tsx',
|
||||
IconToggleLeft: 'src/components/Icon/icons/IconToggleLeft/index.tsx',
|
||||
IconToggleRight: 'src/components/Icon/icons/IconToggleRight/index.tsx',
|
||||
IconTool: 'src/components/Icon/icons/IconTool/index.tsx',
|
||||
IconTrash2: 'src/components/Icon/icons/IconTrash2/index.tsx',
|
||||
IconTrash: 'src/components/Icon/icons/IconTrash/index.tsx',
|
||||
IconTrello: 'src/components/Icon/icons/IconTrello/index.tsx',
|
||||
IconTrendingDown: 'src/components/Icon/icons/IconTrendingDown/index.tsx',
|
||||
IconTrendingUp: 'src/components/Icon/icons/IconTrendingUp/index.tsx',
|
||||
IconTriangle: 'src/components/Icon/icons/IconTriangle/index.tsx',
|
||||
IconTruck: 'src/components/Icon/icons/IconTruck/index.tsx',
|
||||
IconTv: 'src/components/Icon/icons/IconTv/index.tsx',
|
||||
IconTwitch: 'src/components/Icon/icons/IconTwitch/index.tsx',
|
||||
IconTwitter: 'src/components/Icon/icons/IconTwitter/index.tsx',
|
||||
IconType: 'src/components/Icon/icons/IconType/index.tsx',
|
||||
IconUmbrella: 'src/components/Icon/icons/IconUmbrella/index.tsx',
|
||||
IconUnderline: 'src/components/Icon/icons/IconUnderline/index.tsx',
|
||||
IconUnlock: 'src/components/Icon/icons/IconUnlock/index.tsx',
|
||||
IconUploadCloud: 'src/components/Icon/icons/IconUploadCloud/index.tsx',
|
||||
IconUpload: 'src/components/Icon/icons/IconUpload/index.tsx',
|
||||
IconUserCheck: 'src/components/Icon/icons/IconUserCheck/index.tsx',
|
||||
IconUserMinus: 'src/components/Icon/icons/IconUserMinus/index.tsx',
|
||||
IconUserPlus: 'src/components/Icon/icons/IconUserPlus/index.tsx',
|
||||
IconUserX: 'src/components/Icon/icons/IconUserX/index.tsx',
|
||||
IconUser: 'src/components/Icon/icons/IconUser/index.tsx',
|
||||
IconUsers: 'src/components/Icon/icons/IconUsers/index.tsx',
|
||||
IconVideoOff: 'src/components/Icon/icons/IconVideoOff/index.tsx',
|
||||
IconVideo: 'src/components/Icon/icons/IconVideo/index.tsx',
|
||||
IconVoicemail: 'src/components/Icon/icons/IconVoicemail/index.tsx',
|
||||
IconVolume1: 'src/components/Icon/icons/IconVolume1/index.tsx',
|
||||
IconVolume2: 'src/components/Icon/icons/IconVolume2/index.tsx',
|
||||
IconVolumeX: 'src/components/Icon/icons/IconVolumeX/index.tsx',
|
||||
IconVolume: 'src/components/Icon/icons/IconVolume/index.tsx',
|
||||
IconWatch: 'src/components/Icon/icons/IconWatch/index.tsx',
|
||||
IconWifiOff: 'src/components/Icon/icons/IconWifiOff/index.tsx',
|
||||
IconWifi: 'src/components/Icon/icons/IconWifi/index.tsx',
|
||||
IconWind: 'src/components/Icon/icons/IconWind/index.tsx',
|
||||
IconXCircle: 'src/components/Icon/icons/IconXCircle/index.tsx',
|
||||
IconXOctagon: 'src/components/Icon/icons/IconXOctagon/index.tsx',
|
||||
IconXSquare: 'src/components/Icon/icons/IconXSquare/index.tsx',
|
||||
IconX: 'src/components/Icon/icons/IconX/index.tsx',
|
||||
IconYoutube: 'src/components/Icon/icons/IconYoutube/index.tsx',
|
||||
IconZapOff: 'src/components/Icon/icons/IconZapOff/index.tsx',
|
||||
IconZap: 'src/components/Icon/icons/IconZap/index.tsx',
|
||||
IconZoomIn: 'src/components/Icon/icons/IconZoomIn/index.tsx',
|
||||
IconZoomOut: 'src/components/Icon/icons/IconZoomOut/index.tsx'
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,77 @@
|
||||
const fs = require('fs')
|
||||
const util = require('util')
|
||||
var icons = require('./icons.json') //with path
|
||||
|
||||
let iconList = {}
|
||||
let importList = []
|
||||
|
||||
//
|
||||
// create icon .tsx files
|
||||
//
|
||||
|
||||
Object.values(icons).map((icon) => {
|
||||
iconList[`Icon${icon.name}`] = `src/components/Icon/icons/Icon${icon.name}/index.tsx`
|
||||
importList.push(`export * as Icon${icon.name} from './Icon${icon.name}'`)
|
||||
|
||||
var dir = `src/components/Icon/icons/Icon${icon.name}`
|
||||
|
||||
fs.mkdir(dir, { recursive: true }, (err) => {
|
||||
if (err) throw err
|
||||
})
|
||||
|
||||
fs.writeFile(
|
||||
`${dir}/index.tsx`,
|
||||
`export { default as Icon${icon.name} } from './Icon${icon.name}'`,
|
||||
function (err) {
|
||||
if (err) return console.log(err)
|
||||
}
|
||||
)
|
||||
|
||||
fs.writeFile(
|
||||
`${dir}/Icon${icon.name}.tsx`,
|
||||
`// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { ${icon.name} } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function Icon${icon.name}(props: any) {
|
||||
return <IconBase icon={${icon.name}} {...props} />
|
||||
}
|
||||
|
||||
export default Icon${icon.name}
|
||||
`,
|
||||
function (err) {
|
||||
if (err) return console.log(err)
|
||||
// console.log(`${icon.name} > ${icon.path}`)
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
//
|
||||
// create export file for icons
|
||||
//
|
||||
|
||||
fs.writeFile(
|
||||
`src/components/Icon/icons/index.tsx`,
|
||||
`// export icons
|
||||
${importList
|
||||
.map((icon) => {
|
||||
return `${icon}\n`
|
||||
})
|
||||
.join('')}`,
|
||||
function (err) {
|
||||
if (err) return console.log(err)
|
||||
// console.log(`wrote file for rollup`)
|
||||
}
|
||||
)
|
||||
|
||||
//
|
||||
// create input destinations for rollup
|
||||
//
|
||||
|
||||
fs.writeFile(`internals/icons.js`, `export default ${util.inspect(iconList)}`, function (err) {
|
||||
if (err) return console.log(err)
|
||||
// console.log(`wrote file for rollup`)
|
||||
})
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "ui",
|
||||
"version": "0.0.0",
|
||||
"main": "./index.tsx",
|
||||
"types": "./index.tsx",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build:icons": "node --experimental-modules internals/populate-icons.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.0.0",
|
||||
"@mertasan/tailwindcss-variables": "^2.0.1",
|
||||
"@radix-ui/colors": "^0.1.8",
|
||||
"@radix-ui/react-accordion": "^0.1.5",
|
||||
"@radix-ui/react-collapsible": "^0.1.5",
|
||||
"@radix-ui/react-context-menu": "^0.1.0",
|
||||
"@radix-ui/react-dialog": "^0.1.5",
|
||||
"@radix-ui/react-dropdown-menu": "^0.1.4",
|
||||
"@radix-ui/react-popover": "^0.1.0",
|
||||
"@radix-ui/react-portal": "^0.1.3",
|
||||
"@radix-ui/react-tabs": "^0.1.0",
|
||||
"@tailwindcss/forms": "^0.4.0",
|
||||
"@tailwindcss/typography": "^0.5.0",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"formik": "^2.2.9",
|
||||
"lodash": "^4.17.20",
|
||||
"postcss": "^8.4.5",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-feather": "^2.0.10",
|
||||
"tailwindcss": "^3.0.15",
|
||||
"tailwindcss-radix": "^1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^17.0.37",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"typescript": "4.3.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('config/postcss.config')
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,72 @@
|
||||
/* .sbui-accordion-container {
|
||||
@apply flex flex-col rounded-md;
|
||||
}
|
||||
|
||||
.sbui-accordion-container--bordered {
|
||||
@apply border border-solid;
|
||||
@apply bg-white border-gray-200;
|
||||
@apply dark:bg-dark-700 dark:border-darkmode;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item {
|
||||
@apply w-full;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item__button {
|
||||
@apply flex justify-between w-full text-left cursor-pointer px-6 py-4 border-0 border-solid font-medium text-base rounded-t-md bg-transparent;
|
||||
|
||||
@apply border-gray-200 text-gray-500 hover:text-gray-600;
|
||||
@apply dark:border-darkmode dark:text-dark-200 dark:hover:text-white;
|
||||
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item__button .sbui-typography-text {
|
||||
@apply w-full max-w-none;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item__button .sbui-typography-text:last-child {
|
||||
@apply pl-2;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item__button .sbui-icon {
|
||||
@apply mt-px;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item__button--open .sbui-icon {
|
||||
@apply transform rotate-180;
|
||||
} */
|
||||
/*
|
||||
.sbui-accordion-container--bordered
|
||||
.sbui-accordion-item__button:not(:first-child) {
|
||||
@apply rounded-none border-t border-gray-200 dark:border-darkmode;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item__panel {
|
||||
@apply px-6 py-4;
|
||||
} */
|
||||
|
||||
/* .sbui-accordion-item__panel--enter {
|
||||
@apply transition-max-height ease-in-out duration-700 overflow-hidden;
|
||||
}
|
||||
|
||||
.sbui-accordion-item__panel--enterFrom {
|
||||
@apply max-h-0;
|
||||
}
|
||||
|
||||
.sbui-accordion-item__panel--enterTo {
|
||||
@apply max-h-screen;
|
||||
}
|
||||
|
||||
.sbui-accordion-item__panel--leave {
|
||||
@apply transition-max-height ease-in-out duration-300 overflow-hidden;
|
||||
}
|
||||
|
||||
.sbui-accordion-item__panel--leaveFrom {
|
||||
@apply max-h-screen;
|
||||
}
|
||||
|
||||
.sbui-accordion-item__panel--leaveTo {
|
||||
@apply max-h-0;
|
||||
} */
|
||||
@@ -0,0 +1,201 @@
|
||||
import React from 'react'
|
||||
|
||||
import { Accordion } from '.'
|
||||
import { Typography } from '../Typography'
|
||||
import { IconArrowUp } from '../Icon/icons/IconArrowUp'
|
||||
import { Badge } from '../Badge'
|
||||
|
||||
export default {
|
||||
title: 'Displays/Accordion',
|
||||
component: Accordion,
|
||||
}
|
||||
|
||||
export const OneItem = (args: any) => (
|
||||
<Accordion {...args} justified={false}>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<>
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
<Badge>Test badge</Badge>
|
||||
</>
|
||||
}
|
||||
id="first"
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
)
|
||||
|
||||
export const MultipleItems = (args: any) => (
|
||||
<Accordion {...args} openBehaviour="multiple">
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'1'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'2'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'3'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'4'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
)
|
||||
|
||||
export const Bordered = (args: any) => (
|
||||
<Accordion {...args}>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'1'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'2'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'3'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Title of the thing
|
||||
</span>
|
||||
}
|
||||
id={'4'}
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
)
|
||||
|
||||
Bordered.args = {
|
||||
type: 'bordered',
|
||||
}
|
||||
|
||||
export const LeftAlignedChevron = (args: any) => (
|
||||
<Accordion {...args} justified={false} chevronAlign="left">
|
||||
<Accordion.Item
|
||||
header={
|
||||
<>
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
First item
|
||||
</span>
|
||||
<Badge>Test badge</Badge>
|
||||
</>
|
||||
}
|
||||
id="first"
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
<Accordion.Item
|
||||
header={
|
||||
<>
|
||||
<span className="text-scale-900 group-hover:text-scale-1200">
|
||||
Second item
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
id="second"
|
||||
>
|
||||
<span className="text-scale-900">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur
|
||||
amet labore.
|
||||
</span>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
)
|
||||
|
||||
// export const withDefaultActive = Multiple.bind({})
|
||||
// withDefaultActive.args = {
|
||||
// defaultActiveId: [1],
|
||||
// }
|
||||
|
||||
// export const withIconLeft = Multiple.bind({})
|
||||
// withIconLeft.args = {
|
||||
// iconPosition: 'left',
|
||||
// }
|
||||
|
||||
// export const withCustomIcon = Multiple.bind({})
|
||||
// withCustomIcon.args = {
|
||||
// icon: <IconArrowUp />,
|
||||
// }
|
||||
@@ -0,0 +1,152 @@
|
||||
import React, { createContext, useContext, useState } from 'react'
|
||||
|
||||
import { IconChevronUp } from '../Icon/icons/IconChevronUp'
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
|
||||
import * as RadixAccordion from '@radix-ui/react-accordion'
|
||||
import { IconChevronDown } from '../Icon/icons/IconChevronDown'
|
||||
import { Transition } from '@headlessui/react'
|
||||
|
||||
// type ContextValue = Required<
|
||||
// Pick<AccordionProps, 'defaultActiveId' | 'icon' | 'iconPosition'>
|
||||
// > &
|
||||
// Pick<AccordionProps, 'onChange'>
|
||||
|
||||
type Type = 'default' | 'bordered'
|
||||
type Size = 'tiny' | 'small' | 'medium' | 'large' | 'xlarge'
|
||||
type Align = 'left' | 'right'
|
||||
|
||||
interface ContextValue {
|
||||
bordered?: boolean
|
||||
type: Type
|
||||
justified: Boolean
|
||||
chevronAlign: Align
|
||||
// currentItems: string[]
|
||||
}
|
||||
|
||||
const AccordionContext = createContext<ContextValue>({
|
||||
chevronAlign: 'left',
|
||||
justified: true,
|
||||
type: 'default',
|
||||
// currentItems: [],
|
||||
})
|
||||
|
||||
interface AccordionProps {
|
||||
children?: React.ReactNode
|
||||
className?: string
|
||||
defaultActiveId?: (string | number)[]
|
||||
icon?: React.ReactNode
|
||||
iconPosition?: Align
|
||||
bordered: boolean
|
||||
onChange?: (item: string | string[]) => void
|
||||
openBehaviour: 'single' | 'multiple'
|
||||
type: Type
|
||||
size: Size
|
||||
defaultValue?: string | string[] | undefined
|
||||
justified: Boolean
|
||||
chevronAlign: Align
|
||||
}
|
||||
|
||||
function Accordion({
|
||||
children,
|
||||
className,
|
||||
defaultActiveId = [],
|
||||
icon = <IconChevronUp strokeWidth={2} />,
|
||||
iconPosition = 'right',
|
||||
onChange,
|
||||
openBehaviour = 'multiple',
|
||||
type = 'default',
|
||||
// size, // TO DO
|
||||
defaultValue = undefined,
|
||||
justified = true,
|
||||
chevronAlign,
|
||||
}: AccordionProps) {
|
||||
// const [currentItems, setCurrentItems] = useState(defaultValue || [])
|
||||
|
||||
const __styles = styleHandler('accordion')
|
||||
|
||||
let containerClasses = [__styles.variants[type].base]
|
||||
|
||||
if (className) {
|
||||
containerClasses.push(className)
|
||||
}
|
||||
|
||||
// let currentItems = defaultValue || []
|
||||
|
||||
const contextValue = {
|
||||
chevronAlign,
|
||||
justified,
|
||||
type,
|
||||
defaultValue,
|
||||
}
|
||||
|
||||
function handleOnChange(e: string | string[]) {
|
||||
if (onChange) onChange(e)
|
||||
const value = e == typeof String ? e.split(' ') : e
|
||||
// setCurrentItems(e)
|
||||
console.log('about to change state')
|
||||
// currentItems = e
|
||||
// console.log('currentItems', currentItems)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* @ts-ignore */}
|
||||
<RadixAccordion.Root
|
||||
type={openBehaviour}
|
||||
onValueChange={handleOnChange}
|
||||
defaultValue={defaultValue}
|
||||
className={containerClasses.join(' ')}
|
||||
children={
|
||||
<AccordionContext.Provider value={{ ...contextValue }}>
|
||||
<div className={containerClasses.join(' ')}>{children}</div>
|
||||
</AccordionContext.Provider>
|
||||
}
|
||||
></RadixAccordion.Root>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
interface ItemProps {
|
||||
children?: React.ReactNode
|
||||
className?: string
|
||||
header: React.ReactNode
|
||||
id: string
|
||||
icon?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Item({ children, className, header, id, icon }: ItemProps) {
|
||||
const __styles = styleHandler('accordion')
|
||||
// const [open, setOpen] = useState(false)
|
||||
|
||||
const {
|
||||
type,
|
||||
justified,
|
||||
chevronAlign,
|
||||
// currentItems,
|
||||
// defaultActiveId, iconPosition, onChange
|
||||
} = useContext(AccordionContext)
|
||||
|
||||
let triggerClasses = [__styles.variants[type].trigger]
|
||||
if (justified) triggerClasses.push(__styles.justified)
|
||||
if (className) triggerClasses.push(className)
|
||||
|
||||
let chevronClasses = [__styles.chevron.base, __styles.chevron.align[chevronAlign]]
|
||||
|
||||
// console.log('currentItems', currentItems)
|
||||
|
||||
return (
|
||||
<RadixAccordion.Item value={id} className={__styles.variants[type].container}>
|
||||
<RadixAccordion.Trigger className={triggerClasses.join(' ')}>
|
||||
{header}
|
||||
<IconChevronDown aria-hidden className={chevronClasses.join(' ')} strokeWidth={2} />
|
||||
</RadixAccordion.Trigger>
|
||||
<RadixAccordion.Content className={__styles.variants[type].content}>
|
||||
<div className={__styles.variants[type].panel}>{children}</div>
|
||||
</RadixAccordion.Content>
|
||||
</RadixAccordion.Item>
|
||||
)
|
||||
}
|
||||
|
||||
Accordion.Item = Item
|
||||
export default Accordion
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Accordion } from './Accordion'
|
||||
@@ -0,0 +1,63 @@
|
||||
/* .sbui-alert-container {
|
||||
@apply rounded-md p-4;
|
||||
}
|
||||
|
||||
.sbui-alert-container--danger {
|
||||
@apply bg-red-600 bg-opacity-10 text-red-600;
|
||||
}
|
||||
|
||||
.sbui-alert-container--warning {
|
||||
@apply bg-yellow-600 bg-opacity-10 text-yellow-600;
|
||||
}
|
||||
|
||||
.sbui-alert-container--info {
|
||||
@apply bg-blue-600 bg-opacity-10 text-blue-600;
|
||||
}
|
||||
|
||||
.sbui-alert-container--success {
|
||||
@apply bg-green-600 bg-opacity-10 text-green-600;
|
||||
} */
|
||||
|
||||
/* .sbui-alert-title {
|
||||
@apply m-0 text-sm font-medium;
|
||||
}
|
||||
|
||||
.sbui-alert-description {
|
||||
@apply mt-2 text-sm;
|
||||
}
|
||||
|
||||
.sbui-alert-description--danger {
|
||||
@apply text-red-500;
|
||||
}
|
||||
|
||||
.sbui-alert-description--warning {
|
||||
@apply text-yellow-500;
|
||||
}
|
||||
|
||||
.sbui-alert-description--info {
|
||||
@apply text-blue-500;
|
||||
}
|
||||
|
||||
.sbui-alert-description--success {
|
||||
@apply text-green-500;
|
||||
}
|
||||
|
||||
.sbui-close-button {
|
||||
@apply cursor-pointer inline-flex transition ease-in-out duration-200 bg-transparent border-transparent rounded-md p-1.5 focus:outline-none;
|
||||
}
|
||||
|
||||
.sbui-close-button--success {
|
||||
@apply text-green-500 hover:bg-green-600 hover:bg-opacity-10;
|
||||
}
|
||||
|
||||
.sbui-close-button--danger {
|
||||
@apply text-red-500 hover:bg-red-600 hover:bg-opacity-10;
|
||||
}
|
||||
|
||||
.sbui-close-button--warning {
|
||||
@apply text-yellow-500 hover:bg-yellow-600 hover:bg-opacity-10;
|
||||
}
|
||||
|
||||
.sbui-close-button--info {
|
||||
@apply text-blue-500 hover:bg-blue-600 hover:bg-opacity-10;
|
||||
} */
|
||||
@@ -0,0 +1,137 @@
|
||||
import React from 'react'
|
||||
|
||||
import { Alert } from './../../../'
|
||||
|
||||
// import ThemeProvider from '../../theme/themeContext'
|
||||
|
||||
export default {
|
||||
title: 'Displays/Alerts',
|
||||
component: Alert,
|
||||
}
|
||||
|
||||
export const Neutral = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const Success = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const SuccessWithIcon = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const Danger = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const DangerWithIcon = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const Info = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const InfoWithIcon = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const Warning = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const WarningWithIcon = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const Closable = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
export const WithAction = (args: any) => (
|
||||
<Alert {...args}>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur amet labore.
|
||||
</Alert>
|
||||
)
|
||||
|
||||
Neutral.args = {
|
||||
title: 'Success alert with icon',
|
||||
withIcon: true,
|
||||
}
|
||||
|
||||
Success.args = {
|
||||
title: 'Success alert',
|
||||
variant: 'success',
|
||||
}
|
||||
|
||||
SuccessWithIcon.args = {
|
||||
title: 'Success alert with icon',
|
||||
variant: 'success',
|
||||
withIcon: true,
|
||||
}
|
||||
|
||||
Danger.args = {
|
||||
title: 'Danger alert',
|
||||
variant: 'danger',
|
||||
}
|
||||
|
||||
DangerWithIcon.args = {
|
||||
title: 'Danger alert with icon',
|
||||
variant: 'danger',
|
||||
withIcon: true,
|
||||
}
|
||||
|
||||
Info.args = {
|
||||
title: 'Info alert',
|
||||
variant: 'info',
|
||||
}
|
||||
|
||||
InfoWithIcon.args = {
|
||||
title: 'Info alert with icon',
|
||||
variant: 'info',
|
||||
withIcon: true,
|
||||
}
|
||||
|
||||
Warning.args = {
|
||||
title: 'Warning alert',
|
||||
variant: 'warning',
|
||||
}
|
||||
|
||||
WarningWithIcon.args = {
|
||||
title: 'Warning alert with icon',
|
||||
variant: 'warning',
|
||||
withIcon: true,
|
||||
}
|
||||
|
||||
Closable.args = {
|
||||
title: 'Closable alert',
|
||||
closable: true,
|
||||
}
|
||||
|
||||
WithAction.args = {
|
||||
title: 'Alert with action',
|
||||
variant: 'warning',
|
||||
withIcon: true,
|
||||
actions: <div>Hello</div>,
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import Alert from './Alert'
|
||||
|
||||
const VARIANTS = ['success', 'danger', 'warning', 'info']
|
||||
|
||||
describe('#Alert', () => {
|
||||
it('should render elements correctly', () => {
|
||||
render(<Alert title="Required Title">{'Description'}</Alert>)
|
||||
expect(screen.queryByText('Required Title')).toBeInTheDocument()
|
||||
expect(screen.queryByText('Description')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should add custom classes to container div', () => {
|
||||
const { container } = render(
|
||||
<Alert title="Required Title" className={'custom classes'}>
|
||||
{'Description'}
|
||||
</Alert>
|
||||
)
|
||||
expect(container.querySelector('div')).toHaveClass(
|
||||
`sbui-alert-container sbui-alert-container--success custom classes`
|
||||
)
|
||||
})
|
||||
|
||||
it('should close alert when close button clicked', () => {
|
||||
render(
|
||||
<Alert title="Required Title" closable>
|
||||
{'Description'}
|
||||
</Alert>
|
||||
)
|
||||
|
||||
const closeButton = screen.getByRole('button')
|
||||
|
||||
fireEvent.click(closeButton)
|
||||
|
||||
expect(screen.queryByText('Description')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render an icon when passed withIcon', () => {
|
||||
const { container } = render(
|
||||
<Alert title="Required Title" withIcon>
|
||||
{'Description'}
|
||||
</Alert>
|
||||
)
|
||||
|
||||
expect(
|
||||
container.querySelector('div.flex-shrink-0 > svg')
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it.each(VARIANTS)(
|
||||
'should have "sbui-alert-[container|description]--%s" class',
|
||||
(variant) => {
|
||||
const { container } = render(
|
||||
<Alert title="Required Title" variant={variant}>
|
||||
{'Description'}
|
||||
</Alert>
|
||||
)
|
||||
|
||||
expect(container.querySelector('div')).toHaveClass(
|
||||
`sbui-alert-container sbui-alert-container--${variant}`
|
||||
)
|
||||
expect(screen.queryByText('Description')).toHaveClass(
|
||||
`sbui-alert-description sbui-alert-description--${variant}`
|
||||
)
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,99 @@
|
||||
import React, { useState } from 'react'
|
||||
import { IconAlertTriangle } from '../Icon/icons/IconAlertTriangle'
|
||||
|
||||
import { IconInfo } from '../Icon/icons/IconInfo'
|
||||
import { IconX } from '../Icon/icons/IconX'
|
||||
|
||||
// @ts-ignore
|
||||
// import AlertStyles from './Alert.module.css'
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
import { IconAlertOctagon } from '../Icon/icons/IconAlertOctagon'
|
||||
import { IconCheckCircle } from '../Icon/icons/IconCheckCircle'
|
||||
|
||||
interface Props {
|
||||
variant?: 'success' | 'danger' | 'warning' | 'info' | 'neutral'
|
||||
className?: string
|
||||
title: string
|
||||
withIcon?: boolean
|
||||
closable?: boolean
|
||||
children?: React.ReactNode
|
||||
icon?: React.ReactNode
|
||||
actions?: React.ReactNode
|
||||
}
|
||||
|
||||
const icons: Record<
|
||||
'success' | 'danger' | 'warning' | 'info' | 'neutral',
|
||||
React.ReactElement
|
||||
> = {
|
||||
danger: <IconAlertOctagon strokeWidth={1.5} size={18} />,
|
||||
success: <IconCheckCircle strokeWidth={1.5} size={18} />,
|
||||
warning: <IconAlertTriangle strokeWidth={1.5} size={18} />,
|
||||
info: <IconInfo strokeWidth={1.5} size={18} />,
|
||||
neutral: <></>,
|
||||
}
|
||||
|
||||
function Alert({
|
||||
variant = 'neutral',
|
||||
className,
|
||||
title,
|
||||
withIcon,
|
||||
closable,
|
||||
children,
|
||||
icon,
|
||||
actions,
|
||||
}: Props) {
|
||||
let __styles = styleHandler('alert')
|
||||
|
||||
const [visible, setVisible] = useState(true)
|
||||
|
||||
let containerClasses = [__styles.base]
|
||||
containerClasses.push(__styles.variant[variant].base)
|
||||
|
||||
if (className) containerClasses.push(className)
|
||||
|
||||
let descriptionClasses = [
|
||||
__styles.description,
|
||||
__styles.variant[variant].description,
|
||||
]
|
||||
let closeButtonClasses = [__styles.close]
|
||||
|
||||
return (
|
||||
<>
|
||||
{visible && (
|
||||
<div className={containerClasses.join(' ')}>
|
||||
{withIcon ? (
|
||||
<div className={__styles.variant[variant].icon}>
|
||||
{withIcon && icons[variant]}
|
||||
</div>
|
||||
) : null}
|
||||
{icon && icon}
|
||||
<div className="flex flex-1 items-center justify-between">
|
||||
<div>
|
||||
<h3
|
||||
className={[
|
||||
__styles.variant[variant].header,
|
||||
__styles.header,
|
||||
].join(' ')}
|
||||
>
|
||||
{title}
|
||||
</h3>
|
||||
<div className={descriptionClasses.join(' ')}>{children}</div>
|
||||
</div>
|
||||
{actions}
|
||||
</div>
|
||||
{closable && (
|
||||
<button
|
||||
aria-label="Close alert"
|
||||
onClick={() => setVisible(false)}
|
||||
className={closeButtonClasses.join(' ')}
|
||||
>
|
||||
<IconX strokeWidth={2} size={16} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Alert
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Alert } from './Alert'
|
||||
@@ -0,0 +1,65 @@
|
||||
.sbui-avatar {
|
||||
@apply rounded-full;
|
||||
}
|
||||
|
||||
.sbui-avatar-type-rounded {
|
||||
border-radius: 10%;
|
||||
}
|
||||
|
||||
.sbui-avatar-type-square {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.sbui-avatar-image {
|
||||
object-fit: 'contain';
|
||||
border-radius: '50%';
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.sbui-avatar-children {
|
||||
@apply flex;
|
||||
@apply justify-center;
|
||||
@apply items-center
|
||||
}
|
||||
|
||||
.sbui-avatar-icon {
|
||||
@apply flex;
|
||||
@apply justify-center;
|
||||
@apply items-center;
|
||||
background-color: cadetblue;
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.sbui-avatar-text {
|
||||
@apply flex;
|
||||
@apply justify-center;
|
||||
@apply items-center;
|
||||
background-color: cadetblue;
|
||||
float: left;
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.sbui-avatar-fallback {
|
||||
@apply flex;
|
||||
@apply justify-center;
|
||||
@apply items-center;
|
||||
background-color: cadetblue;
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
}
|
||||
|
||||
.sbui-avatar-single {
|
||||
|
||||
}
|
||||
|
||||
.sbui-avatar-multiple {
|
||||
|
||||
}
|
||||
|
||||
.sbui-image-responsive {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import React from 'react'
|
||||
import { IconAirplay } from '../Icon/icons/IconAirplay'
|
||||
|
||||
import Avatar from './Avatar'
|
||||
|
||||
export default {
|
||||
title: 'General/Avatar',
|
||||
component: Avatar,
|
||||
}
|
||||
|
||||
export const Image = (args: any) => {
|
||||
return (
|
||||
<>
|
||||
<Avatar {...args} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const Text = (args: any) => {
|
||||
return (
|
||||
<>
|
||||
<Avatar {...args} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const Icon = (args: any) => {
|
||||
return (
|
||||
<>
|
||||
<Avatar {...args} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const Fallback = (args: any) => {
|
||||
return (
|
||||
<>
|
||||
<Avatar {...args} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Image.args = {
|
||||
active: true,
|
||||
src: 'https://via.placeholder.com/150',
|
||||
}
|
||||
|
||||
Text.args = {
|
||||
active: true,
|
||||
text: 'Shoury',
|
||||
}
|
||||
|
||||
Icon.args = {
|
||||
active: true,
|
||||
Icon: IconAirplay,
|
||||
}
|
||||
|
||||
Fallback.args = {
|
||||
active: true,
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
import React from 'react'
|
||||
import { Icon } from '../Icon/IconImportHandler'
|
||||
import { IconUser } from '../Icon/icons/IconUser'
|
||||
// @ts-ignore
|
||||
import AvatarStyles from './Avatar.module.css'
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode
|
||||
src?: string | undefined
|
||||
style?: React.CSSProperties
|
||||
className?: string
|
||||
alt?: string
|
||||
responsive?: boolean
|
||||
text?: string
|
||||
variant?: 'circle' | 'square'
|
||||
AvatarIcon?: Icon
|
||||
size: number
|
||||
}
|
||||
|
||||
export default function Avatar({
|
||||
src,
|
||||
style,
|
||||
className,
|
||||
alt,
|
||||
responsive,
|
||||
text,
|
||||
variant,
|
||||
AvatarIcon,
|
||||
size,
|
||||
children,
|
||||
}: Props) {
|
||||
const classes = [AvatarStyles['sbui-avatar']]
|
||||
classes.push(className)
|
||||
let objectToRender
|
||||
|
||||
const imageExist = () => {
|
||||
const img = new Image()
|
||||
img.src = src
|
||||
if (img.complete) {
|
||||
return true
|
||||
} else {
|
||||
img.onload = () => {
|
||||
return true
|
||||
}
|
||||
img.onerror = () => {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imageExist && src) {
|
||||
classes.push(AvatarStyles['sbui-avatar-image'])
|
||||
objectToRender = (
|
||||
<img
|
||||
className={classes.join(' ')}
|
||||
src={src}
|
||||
alt={alt}
|
||||
style={{ height: size, width: size, ...style }}
|
||||
/>
|
||||
)
|
||||
} else if (AvatarIcon) {
|
||||
classes.push(AvatarStyles['sbui-avatar-icon'])
|
||||
objectToRender = (
|
||||
<div
|
||||
className={classes.join(' ')}
|
||||
style={{ height: size, width: size, ...style }}
|
||||
>
|
||||
<AvatarIcon />
|
||||
</div>
|
||||
)
|
||||
} else if (text) {
|
||||
classes.push(AvatarStyles['sbui-avatar-text'])
|
||||
objectToRender = (
|
||||
<div
|
||||
className={classes.join(' ')}
|
||||
style={{ height: size, width: size, ...style }}
|
||||
>
|
||||
<p>{text[0]}</p>
|
||||
</div>
|
||||
)
|
||||
} else if (children) {
|
||||
classes.push(AvatarStyles['sbui-avatar-children'])
|
||||
objectToRender = (
|
||||
<div
|
||||
className={classes.join(' ')}
|
||||
style={{ height: size, width: size, ...style }}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
classes.push(AvatarStyles['sbui-avatar-fallback'])
|
||||
objectToRender = (
|
||||
<div
|
||||
className={classes.join(' ')}
|
||||
style={{ height: size, width: size, ...style }}
|
||||
>
|
||||
<IconUser />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return <>{objectToRender}</>
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Image } from './Avatar'
|
||||
@@ -0,0 +1,43 @@
|
||||
/* .sbui-badge {
|
||||
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-500 bg-opacity-10 text-brand-800;
|
||||
}
|
||||
|
||||
.sbui-badge--large {
|
||||
@apply px-3 py-0.5 rounded-full text-sm;
|
||||
}
|
||||
|
||||
.sbui-badge-dot {
|
||||
@apply -ml-0.5 mr-1.5 h-2 w-2;
|
||||
}
|
||||
|
||||
.sbui-badge--gray {
|
||||
@apply bg-gray-600 bg-opacity-10 text-gray-500;
|
||||
}
|
||||
|
||||
.sbui-badge--red {
|
||||
@apply bg-red-600 bg-opacity-10 text-red-500;
|
||||
}
|
||||
|
||||
.sbui-badge--yellow {
|
||||
@apply bg-yellow-600 bg-opacity-10 text-yellow-500;
|
||||
}
|
||||
|
||||
.sbui-badge--green {
|
||||
@apply bg-green-600 bg-opacity-10 text-green-500;
|
||||
}
|
||||
|
||||
.sbui-badge--blue {
|
||||
@apply bg-blue-600 bg-opacity-10 text-blue-500;
|
||||
}
|
||||
|
||||
.sbui-badge--indigo {
|
||||
@apply bg-indigo-600 bg-opacity-10 text-indigo-500;
|
||||
}
|
||||
|
||||
.sbui-badge--purple {
|
||||
@apply bg-purple-600 bg-opacity-10 text-purple-500;
|
||||
}
|
||||
|
||||
.sbui-badge--pink {
|
||||
@apply bg-pink-600 bg-opacity-10 text-pink-500;
|
||||
} */
|
||||
@@ -0,0 +1,98 @@
|
||||
import { Badge } from './'
|
||||
|
||||
export default {
|
||||
title: 'Displays/Badge',
|
||||
component: Badge,
|
||||
}
|
||||
|
||||
const colors = [
|
||||
'brand',
|
||||
'scale',
|
||||
'tomato',
|
||||
'red',
|
||||
'crimson',
|
||||
'pink',
|
||||
'plum',
|
||||
'purple',
|
||||
'violet',
|
||||
'indigo',
|
||||
'blue',
|
||||
'cyan',
|
||||
'teal',
|
||||
'green',
|
||||
'grass',
|
||||
'brown',
|
||||
'orange',
|
||||
'sky',
|
||||
'mint',
|
||||
'lime',
|
||||
'yellow',
|
||||
'amber',
|
||||
'gold',
|
||||
'bronze',
|
||||
'gray',
|
||||
'mauve',
|
||||
'slate',
|
||||
'sage',
|
||||
'olive',
|
||||
'sand',
|
||||
]
|
||||
|
||||
const sizes: string[] = ['small', 'large']
|
||||
|
||||
export const Default = (args: any) => <Badge {...args}>Hello world</Badge>
|
||||
|
||||
export const withColor = (args: any) => <Badge {...args}>Hello world</Badge>
|
||||
|
||||
export const withDot = (args: any) => <Badge {...args}>Hello world</Badge>
|
||||
|
||||
export const large = (args: any) => <Badge {...args}>Hello world</Badge>
|
||||
|
||||
export const withDotLarge = (args: any) => <Badge {...args}>Hello world</Badge>
|
||||
|
||||
export const withCustomClassNames = (args: any) => (
|
||||
<Badge {...args}>Hello world</Badge>
|
||||
)
|
||||
|
||||
export const allBadges = () => (
|
||||
<>
|
||||
<div className="flex flex-row gap-6 mx-auto my-4">
|
||||
{sizes.map((size, sizeIndex) => (
|
||||
<>
|
||||
<h3 className="text-scale-900">{size}</h3>
|
||||
<div className="flex flex-col gap-2">
|
||||
{colors.map((x, colorIndex) => (
|
||||
// @ts-ignore
|
||||
<Badge size={sizes[sizeIndex]} color={colors[colorIndex]}>
|
||||
Supabase
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
Default.args = {}
|
||||
|
||||
withColor.args = {
|
||||
color: 'red',
|
||||
}
|
||||
|
||||
withDot.args = {
|
||||
dot: true,
|
||||
}
|
||||
|
||||
large.args = {
|
||||
size: 'large',
|
||||
}
|
||||
|
||||
withDotLarge.args = {
|
||||
size: 'large',
|
||||
dot: true,
|
||||
}
|
||||
|
||||
withCustomClassNames.args = {
|
||||
className: 'border-teal-100 border-2'
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import Badge from './Badge'
|
||||
|
||||
const SIZES = ['small', 'large']
|
||||
const COLORS = [
|
||||
'gray',
|
||||
'red',
|
||||
'yellow',
|
||||
'green',
|
||||
'blue',
|
||||
'indigo',
|
||||
'purple',
|
||||
'pink'
|
||||
]
|
||||
|
||||
describe('#Badge', () => {
|
||||
it('should render component correctly', () => {
|
||||
const wrapper = render(<Badge>Badge</Badge>)
|
||||
expect(screen.getByText('Badge')).toBeInTheDocument()
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should render different text', () => {
|
||||
const wrapper = render(<Badge>Badge</Badge>)
|
||||
expect(screen.getByText('Badge')).toBeInTheDocument()
|
||||
wrapper.rerender(<Badge>徽章</Badge>)
|
||||
expect(screen.getByText('徽章')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render with dot', () => {
|
||||
const wrapper = render(<Badge dot={true}>Badge</Badge>)
|
||||
expect(screen.getByText('Badge')).toBeInTheDocument()
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it.each(COLORS)('should have %s color', (color) => {
|
||||
render(<Badge color={color}>{color}</Badge>)
|
||||
expect(screen.getByText(color)).toHaveClass(
|
||||
`sbui-badge sbui-badge--${color}`
|
||||
)
|
||||
})
|
||||
|
||||
it.each(SIZES)('should render with %s size', (size) => {
|
||||
render(<Badge size={size}>{size}</Badge>)
|
||||
expect(screen.getByText(size)).toHaveClass(
|
||||
`sbui-badge ${size === 'large' ? 'sbui-badge--large' : ''}`
|
||||
)
|
||||
})
|
||||
|
||||
it('should render with Classes',()=>{
|
||||
render(<Badge className='border-2'>Badge</Badge>)
|
||||
expect(screen.getByText('Badge')).toHaveClass('border-2')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,71 @@
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
|
||||
interface Props {
|
||||
color?:
|
||||
| 'brand'
|
||||
| 'scale'
|
||||
| 'tomato'
|
||||
| 'red'
|
||||
| 'crimson'
|
||||
| 'pink'
|
||||
| 'plum'
|
||||
| 'purple'
|
||||
| 'violet'
|
||||
| 'indigo'
|
||||
| 'blue'
|
||||
| 'cyan'
|
||||
| 'teal'
|
||||
| 'green'
|
||||
| 'grass'
|
||||
| 'brown'
|
||||
| 'orange'
|
||||
| 'sky'
|
||||
| 'mint'
|
||||
| 'lime'
|
||||
| 'yellow'
|
||||
| 'amber'
|
||||
| 'gold'
|
||||
| 'bronze'
|
||||
| 'gray'
|
||||
| 'mauve'
|
||||
| 'slate'
|
||||
| 'sage'
|
||||
| 'olive'
|
||||
| 'sand'
|
||||
children: string | React.ReactNode
|
||||
size?: 'large' | 'small'
|
||||
dot?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
function Badge({ color = 'brand', children, size, dot, className }: Props) {
|
||||
const __styles = styleHandler('badge')
|
||||
|
||||
let classes = [__styles.base]
|
||||
if (color) {
|
||||
classes.push(__styles.color[color])
|
||||
}
|
||||
if (size === 'large') {
|
||||
classes.push(__styles.size.large)
|
||||
}
|
||||
if (className) {
|
||||
classes.push(className)
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={classes.join(' ')}>
|
||||
{dot && (
|
||||
<svg
|
||||
className={`${__styles.dot} ${__styles.color[color]}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 8 8"
|
||||
>
|
||||
<circle cx="4" cy="4" r="3" />
|
||||
</svg>
|
||||
)}
|
||||
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
export default Badge
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Badge } from './Badge'
|
||||
@@ -0,0 +1,34 @@
|
||||
.sbui-breadcrumb--container {
|
||||
@apply flex flex-row items-center;
|
||||
@apply p-0 my-0;
|
||||
}
|
||||
|
||||
.sbui-breadcrumb--item-container {
|
||||
@apply flex items-center;
|
||||
}
|
||||
|
||||
.sbui-breadcrumb--item {
|
||||
@apply text-gray-500 hover:text-gray-600;
|
||||
@apply cursor-pointer;
|
||||
@apply dark:text-dark-200 dark:hover:text-brand-700;
|
||||
}
|
||||
|
||||
.sbui-breadcrumb--item__active {
|
||||
@apply text-brand-700 dark:text-brand-700;
|
||||
}
|
||||
|
||||
.sbui-breadcrumb--separator {
|
||||
@apply mx-2;
|
||||
@apply text-gray-500 hover:text-gray-600;
|
||||
@apply dark:text-dark-200 dark:hover:text-white;
|
||||
}
|
||||
|
||||
.sbui-breadcrumb--separator-small {
|
||||
@apply mx-2;
|
||||
}
|
||||
.sbui-breadcrumb--separator-medium {
|
||||
@apply mx-4;
|
||||
}
|
||||
.sbui-breadcrumb--separator-large {
|
||||
@apply mx-6;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from 'react'
|
||||
import { Breadcrumb } from './../../../'
|
||||
|
||||
export default {
|
||||
title: 'Navigation/Breadcrumb',
|
||||
component: Breadcrumb,
|
||||
}
|
||||
|
||||
export const Default = ({ children, ...args }: any) => <Breadcrumb {...args}>{children}</Breadcrumb>
|
||||
|
||||
Default.args = {
|
||||
children: [
|
||||
<Breadcrumb.Item>Brothers</Breadcrumb.Item>,
|
||||
<Breadcrumb.Item>Grimm</Breadcrumb.Item>,
|
||||
<Breadcrumb.Item active>Hansel</Breadcrumb.Item>,
|
||||
<Breadcrumb.Item>Gretel</Breadcrumb.Item>,
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import Breadcrumb from './Breadcrumb';
|
||||
|
||||
describe('#Breadcrumb', () => {
|
||||
it('should render breadcrumb correctly', async () => {
|
||||
render(
|
||||
<Breadcrumb data-testid="breadcrumb">
|
||||
<p> Item 1 </p>
|
||||
<p> Item 2 </p>
|
||||
</Breadcrumb>
|
||||
)
|
||||
expect(screen.queryByTestId('breadcrumb')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should have "breadcrumb--item" class', () => {
|
||||
render(
|
||||
<Breadcrumb data-testid="breadcrumb">
|
||||
<p> Item 1 </p>
|
||||
<p> Item 2 </p>
|
||||
</Breadcrumb>
|
||||
)
|
||||
expect(screen.queryByTestId('breadcrumb')).toHaveClass('.sbui-breadcrumb--item ')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,62 @@
|
||||
import { IconChevronRight } from '../Icon/icons/IconChevronRight'
|
||||
// @ts-ignore
|
||||
import BreadcrumbStyle from './Breadcrumb.module.css'
|
||||
|
||||
interface Props {
|
||||
children?: [React.ReactNode]
|
||||
className?: string
|
||||
style?: React.CSSProperties
|
||||
spacing?: 'small' | 'medium' | 'large'
|
||||
}
|
||||
|
||||
const Breadcrumb = ({ className, style, children, spacing = 'small' }: Props) => {
|
||||
let classes = [BreadcrumbStyle['sbui-breadcrumb--container']]
|
||||
let seperatorClasses = [BreadcrumbStyle['sbui-breadcrumb--separator']]
|
||||
|
||||
if (className) {
|
||||
classes.push(className)
|
||||
}
|
||||
|
||||
if (spacing) {
|
||||
seperatorClasses.push(`sbui-breadcrumb--separator-${spacing}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<ol className={classes.join(' ')} style={style} aria-label="Breadcrumb">
|
||||
{children!.map((child: React.ReactNode, idx: number) => (
|
||||
<li className={BreadcrumbStyle['sbui-breadcrumb--item-container']}>
|
||||
{child}
|
||||
{idx + 1 < children!.length && (
|
||||
<IconChevronRight size={12} className={seperatorClasses.join(' ')} aria-hidden="true" />
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
)
|
||||
}
|
||||
|
||||
interface ItemProps {
|
||||
children: React.ReactNode
|
||||
active?: boolean
|
||||
onClick?: any
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
export function Item({ children, active, onClick, style }: ItemProps) {
|
||||
let classes = [BreadcrumbStyle['sbui-breadcrumb--item']]
|
||||
if (active) classes.push(BreadcrumbStyle['sbui-breadcrumb--item__active'])
|
||||
return (
|
||||
<span
|
||||
className={classes.join(' ')}
|
||||
onClick={onClick}
|
||||
style={style}
|
||||
aria-current={active ? 'page' : false}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
Breadcrumb.Item = Item
|
||||
|
||||
export default Breadcrumb
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Breadcrumb } from './Breadcrumb'
|
||||
@@ -0,0 +1,156 @@
|
||||
/* .sbui-btn-container {
|
||||
@apply inline-flex font-medium;
|
||||
} */
|
||||
|
||||
/* .sbui-btn {
|
||||
@apply relative cursor-pointer inline-flex items-center space-x-2 text-center border border-solid border-transparent transition ease-out duration-200 outline-none;
|
||||
@apply rounded;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
} */
|
||||
|
||||
/* .sbui-btn:focus {
|
||||
@apply outline-none;
|
||||
} */
|
||||
|
||||
/* .sbui-btn-container--shadow {
|
||||
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
||||
} */
|
||||
|
||||
/* .sbui-btn--w-full {
|
||||
@apply w-full flex items-center justify-center;
|
||||
} */
|
||||
|
||||
/* .sbui-btn:disabled {
|
||||
@apply opacity-75 cursor-not-allowed;
|
||||
pointer-events: none;
|
||||
} */
|
||||
|
||||
/*
|
||||
Button sizes
|
||||
*/
|
||||
|
||||
.sbui-btn--tiny {
|
||||
@apply px-2.5 py-1.5 text-xs;
|
||||
}
|
||||
.sbui-btn--small {
|
||||
@apply px-3 py-2 text-sm leading-4;
|
||||
}
|
||||
.sbui-btn--medium {
|
||||
@apply px-4 py-2 text-sm;
|
||||
}
|
||||
.sbui-btn--large {
|
||||
@apply px-4 py-2 text-base;
|
||||
}
|
||||
.sbui-btn--xlarge {
|
||||
@apply px-6 py-3 text-base;
|
||||
}
|
||||
|
||||
/*
|
||||
Button varients
|
||||
*/
|
||||
/* .sbui-btn-primary {
|
||||
@apply text-white bg-brand-800 hover:bg-brand-600;
|
||||
@apply dark:hover:bg-brand-900;
|
||||
} */
|
||||
.dark .sbui-btn-primary {
|
||||
text-shadow: 0px 0px 4px rgba(38 111 78 / 50%);
|
||||
}
|
||||
|
||||
/* .sbui-btn-default {
|
||||
@apply text-gray-500 bg-white border-gray-200 hover:text-gray-600;
|
||||
@apply hover:bg-white hover:border-gray-200;
|
||||
|
||||
@apply dark:border-gray-600 dark:bg-gray-600 dark:text-dark-200;
|
||||
@apply dark:hover:bg-gray-700;
|
||||
} */
|
||||
.dark .sbui-btn-default {
|
||||
text-shadow: 0px 0px 4px rgba(31 31 31 / 50%);
|
||||
}
|
||||
/*
|
||||
.sbui-btn-secondary {
|
||||
@apply text-gray-600 bg-gray-200;
|
||||
@apply hover:text-gray-700 hover:bg-gray-300;
|
||||
|
||||
@apply dark:text-gray-300 dark:bg-gray-500;
|
||||
@apply dark:hover:bg-gray-600;
|
||||
} */
|
||||
.dark .sbui-btn-secondary {
|
||||
text-shadow: 0px 0px 4px rgba(42 42 42 / 50%);
|
||||
}
|
||||
|
||||
/* .sbui-btn-outline {
|
||||
@apply border text-gray-500 bg-transparent border-gray-200 border-solid hover:bg-white hover:text-gray-600 hover:border-gray-600 dark:text-white dark:border-dark-400 dark:hover:text-dark-600 dark:hover:border-white;
|
||||
} */
|
||||
/* .sbui-btn-dashed {
|
||||
@apply border text-gray-500 bg-transparent border-gray-200 border-dashed hover:text-gray-600 hover:border-gray-600;
|
||||
@apply dark:text-white dark:border-dark-400 dark:hover:text-white dark:hover:border-white;
|
||||
} */
|
||||
/* .sbui-btn-link {
|
||||
@apply bg-transparent text-brand-800 border-none hover:bg-brand-900 hover:bg-opacity-25;
|
||||
box-shadow: none;
|
||||
} */
|
||||
/* .sbui-btn-text {
|
||||
@apply text-gray-400 bg-transparent border-none hover:bg-gray-200 hover:bg-opacity-25;
|
||||
@apply dark:text-dark-300 dark:hover:bg-dark-600;
|
||||
box-shadow: none;
|
||||
} */
|
||||
|
||||
/* .sbui-btn--danger {
|
||||
@apply border-red-500 text-red-500;
|
||||
@apply dark:border-red-500 dark:text-red-500;
|
||||
} */
|
||||
|
||||
/* .dark .sbui-btn--danger {
|
||||
text-shadow: 0px 0px 4px rgba(229, 62, 62 / 50%);
|
||||
}
|
||||
|
||||
.sbui-btn-primary.sbui-btn--danger {
|
||||
@apply bg-red-500 text-white;
|
||||
@apply hover:bg-red-600 hover:border-red-600;
|
||||
}
|
||||
.sbui-btn-default.sbui-btn--danger,
|
||||
.sbui-btn-secondary.sbui-btn--danger,
|
||||
.sbui-btn-outline.sbui-btn--danger,
|
||||
.sbui-btn-dashed.sbui-btn--danger,
|
||||
.sbui-btn-link.sbui-btn--danger,
|
||||
.sbui-btn-text.sbui-btn--danger {
|
||||
@apply hover:bg-red-600 hover:text-white hover:border-red-600;
|
||||
} */
|
||||
/* {
|
||||
@apply hover:bg-red-600 hover:text-white hover:border-red-600;
|
||||
} */
|
||||
|
||||
/*
|
||||
Animation for icon
|
||||
*/
|
||||
/* .sbui-btn--anim--spin {
|
||||
@apply animate-spin;
|
||||
} */
|
||||
|
||||
/* @keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
} */
|
||||
|
||||
/* .sbui-btn-loader--center {
|
||||
position: absolute;
|
||||
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
right: 50%;
|
||||
bottom: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
margin: auto 0;
|
||||
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.sbui-btn--text-fade-out span {
|
||||
@apply opacity-0;
|
||||
} */
|
||||
@@ -0,0 +1,260 @@
|
||||
// import React, { useRef, useState } from 'react'
|
||||
// import defaultTheme from '../../theme/defaultTheme'
|
||||
// import { ThemeProvider } from './../ThemeProvider'
|
||||
// import customThemeExample from '../../lib/theme/customThemeExample'
|
||||
|
||||
import { useRef, useState } from 'react'
|
||||
import { Button, IconPackage, IconChevronRight } from './../../index'
|
||||
|
||||
export default {
|
||||
title: 'General/Button',
|
||||
component: Button,
|
||||
}
|
||||
|
||||
export const Default = (args: any) => <Button {...args}>Button text</Button>
|
||||
export const withStyles = (args: any) => <Button {...args}>Button text</Button>
|
||||
export const withIcon = (args: any) => <Button {...args}>Button text</Button>
|
||||
export const withIconRight = (args: any) => (
|
||||
<Button {...args}>Button text</Button>
|
||||
)
|
||||
export const withBlock = (args: any) => <Button {...args}>Button text</Button>
|
||||
export const withOnlyIcon = (args: any) => <Button {...args} />
|
||||
export const withOnlyLoading = (args: any) => <Button {...args} />
|
||||
export const withLoadingCentered = (args: any) => (
|
||||
<Button {...args}>Loading icon is centered</Button>
|
||||
)
|
||||
export const withRef = () => {
|
||||
const buttonRef = useRef(null)
|
||||
const [msg, setMsg] = useState('Click button to console.log Ref')
|
||||
|
||||
function onClick() {
|
||||
const message = `button:${buttonRef?.current} `
|
||||
setMsg(message)
|
||||
// console.log(message)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button ref={buttonRef} onClick={onClick}>
|
||||
Button with forwardRef
|
||||
</Button>
|
||||
|
||||
<p style={{ color: '#666666' }}>{msg}</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export const allButtons = (args: any) => (
|
||||
<>
|
||||
<div className="flex flex-col space-y-4">
|
||||
<div className="flex space-x-4">
|
||||
<Button {...args} size="tiny">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="default">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="secondary">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="alternative">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="link">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="text">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="dashed">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="outline">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="danger">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="tiny" type="warning">
|
||||
Button text
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-4">
|
||||
<Button {...args} size="small">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="default">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="secondary">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="alternative">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="link">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="text">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="dashed">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="outline">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="danger">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="small" type="warning">
|
||||
Button text
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<Button {...args} size="medium">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="default">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="secondary">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="alternative">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="link">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="text">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="dashed">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="outline">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="danger">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="medium" type="warning">
|
||||
Button text
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<Button {...args} size="large">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="default">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="secondary">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="alternative">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="link">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="text">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="dashed">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="outline">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="danger">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="large" type="warning">
|
||||
Button text
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<Button {...args} size="xlarge">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="default">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="secondary">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="alternative">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="link">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="text">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="dashed">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="outline">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="danger">
|
||||
Button text
|
||||
</Button>
|
||||
<Button {...args} size="xlarge" type="warning">
|
||||
Button text
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
export const withCustomTag = (args: any) => (
|
||||
<Button {...args}>Button text</Button>
|
||||
)
|
||||
|
||||
const icon = <IconPackage />
|
||||
|
||||
withIcon.args = {
|
||||
type: 'primary',
|
||||
icon: icon,
|
||||
}
|
||||
|
||||
withIconRight.args = {
|
||||
type: 'primary',
|
||||
iconRight: <IconChevronRight strokeWidth={2} />,
|
||||
}
|
||||
|
||||
withStyles.args = {
|
||||
type: 'primary',
|
||||
style: { backgroundColor: 'red', color: 'yellow' },
|
||||
}
|
||||
|
||||
withBlock.args = {
|
||||
type: 'primary',
|
||||
block: true,
|
||||
}
|
||||
|
||||
withOnlyIcon.args = {
|
||||
icon: icon,
|
||||
}
|
||||
|
||||
withOnlyLoading.args = {
|
||||
loading: true,
|
||||
}
|
||||
|
||||
withLoadingCentered.args = {
|
||||
loading: true,
|
||||
loadingCentered: true,
|
||||
}
|
||||
|
||||
allButtons.args = {
|
||||
loading: false,
|
||||
danger: false,
|
||||
}
|
||||
|
||||
withCustomTag.args = {
|
||||
as: 'span',
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import React from 'react'
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import Button from './Button'
|
||||
|
||||
const SIZES = ['tiny', 'small', 'medium', 'large', 'xlarge']
|
||||
const TYPES = [
|
||||
'primary',
|
||||
'default',
|
||||
'secondary',
|
||||
'outline',
|
||||
'dashed',
|
||||
'link',
|
||||
'text',
|
||||
]
|
||||
|
||||
describe('#Button', () => {
|
||||
it('should render button correctly', () => {
|
||||
const wrapper = render(<Button>Button</Button>)
|
||||
expect(wrapper.getByText('Button')).toBeInTheDocument()
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should render different text', () => {
|
||||
const wrapper = render(<Button>Button</Button>)
|
||||
expect(screen.getByText('Button')).toBeInTheDocument()
|
||||
wrapper.rerender(<Button>按钮</Button>)
|
||||
expect(screen.getByText('按钮')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should ignore events when disabled', () => {
|
||||
const WrapperButton = () => {
|
||||
const [state, setState] = React.useState('state1')
|
||||
return (
|
||||
<Button disabled onClick={() => setState('state2')}>
|
||||
{state}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
render(<WrapperButton />)
|
||||
expect(screen.getByText('state1')).toBeInTheDocument()
|
||||
fireEvent.click(screen.getByText('state1'))
|
||||
expect(screen.getByText('state1')).toBeInTheDocument()
|
||||
expect(screen.queryByText('state2')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should ignore events when loading', () => {
|
||||
const WrapperButton = () => {
|
||||
const [state, setState] = React.useState('state1')
|
||||
return (
|
||||
<Button loading onClick={() => setState('state2')}>
|
||||
{state}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
render(<WrapperButton />)
|
||||
fireEvent.click(screen.getByText('state1'))
|
||||
expect(screen.queryByText('state2')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should have "w-full" class', async () => {
|
||||
render(<Button block>Button Block</Button>)
|
||||
expect(screen.queryByRole('button')).toHaveClass(
|
||||
'sbui-btn sbui-btn-primary sbui-btn--w-full sbui-btn-container--shadow sbui-btn--tiny'
|
||||
)
|
||||
})
|
||||
|
||||
it.each(TYPES)('should have "btn--%s" class', (type) => {
|
||||
render(<Button type={type}>Button Variant</Button>)
|
||||
|
||||
if (type !== 'text' && type !== 'link') {
|
||||
expect(screen.queryByRole('button')).toHaveClass(
|
||||
`sbui-btn sbui-btn-${type} sbui-btn-container--shadow sbui-btn--tiny`
|
||||
)
|
||||
} else {
|
||||
expect(screen.queryByRole('button')).toHaveClass(
|
||||
`sbui-btn sbui-btn-${type} sbui-btn--tiny`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it.each(SIZES)('should have "btn--%s" class', (size) => {
|
||||
render(<Button size={size}>Button</Button>)
|
||||
expect(screen.queryByRole('button')).toHaveClass(
|
||||
`sbui-btn sbui-btn-primary sbui-btn-container--shadow sbui-btn--${size}`
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,171 @@
|
||||
import React, { forwardRef, useRef, useImperativeHandle } from 'react'
|
||||
import { IconContext } from './../Icon/IconContext'
|
||||
import { IconLoader } from './../Icon/icons/IconLoader'
|
||||
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
|
||||
export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
block?: boolean
|
||||
className?: string
|
||||
children?: React.ReactNode
|
||||
disabled?: boolean
|
||||
onClick?: React.MouseEventHandler<HTMLButtonElement>
|
||||
icon?: React.ReactNode
|
||||
iconRight?: React.ReactNode
|
||||
loading?: boolean
|
||||
loadingCentered?: boolean
|
||||
shadow?: boolean
|
||||
size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge'
|
||||
style?: React.CSSProperties
|
||||
type?:
|
||||
| 'primary'
|
||||
| 'default'
|
||||
| 'secondary'
|
||||
| 'alternative'
|
||||
| 'outline'
|
||||
| 'dashed'
|
||||
| 'link'
|
||||
| 'text'
|
||||
| 'danger'
|
||||
| 'warning'
|
||||
danger?: boolean
|
||||
htmlType?: 'button' | 'submit' | 'reset'
|
||||
ref?: any
|
||||
ariaSelected?: boolean
|
||||
ariaControls?: string
|
||||
tabIndex?: 0 | -1
|
||||
role?: string
|
||||
textAlign?: 'left' | 'center' | 'right'
|
||||
as?: keyof JSX.IntrinsicElements
|
||||
form?: string
|
||||
}
|
||||
|
||||
interface CustomButtonProps extends React.HTMLAttributes<HTMLButtonElement> {}
|
||||
|
||||
interface RefHandle {
|
||||
// container: () => HTMLElement | null
|
||||
button: () => HTMLButtonElement | null
|
||||
}
|
||||
|
||||
export const Button = forwardRef<RefHandle, ButtonProps>(
|
||||
(
|
||||
{
|
||||
block,
|
||||
className,
|
||||
children,
|
||||
danger,
|
||||
disabled = false,
|
||||
onClick,
|
||||
icon,
|
||||
iconRight,
|
||||
loading = false,
|
||||
loadingCentered = false,
|
||||
shadow = true,
|
||||
size = 'tiny',
|
||||
style,
|
||||
type = 'primary',
|
||||
htmlType = 'button',
|
||||
ariaSelected,
|
||||
ariaControls,
|
||||
tabIndex,
|
||||
role,
|
||||
as,
|
||||
textAlign = 'center',
|
||||
...props
|
||||
}: ButtonProps,
|
||||
ref
|
||||
) => {
|
||||
// button ref
|
||||
// const containerRef = useRef<HTMLElement>(null)
|
||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
button: () => {
|
||||
return buttonRef.current
|
||||
},
|
||||
}))
|
||||
|
||||
let __styles = styleHandler('button')
|
||||
|
||||
// styles
|
||||
const showIcon = loading || icon
|
||||
|
||||
let classes = [__styles.base]
|
||||
let containerClasses = [__styles.container]
|
||||
|
||||
classes.push(__styles.type[type])
|
||||
|
||||
if (block) {
|
||||
containerClasses.push(__styles.block)
|
||||
classes.push(__styles.block)
|
||||
}
|
||||
|
||||
if (shadow && type !== 'link' && type !== 'text') {
|
||||
classes.push(__styles.shadow)
|
||||
}
|
||||
|
||||
if (size) {
|
||||
classes.push(__styles.size[size])
|
||||
}
|
||||
|
||||
if (className) {
|
||||
classes.push(className)
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
classes.push(__styles.disabled)
|
||||
}
|
||||
|
||||
const iconLoaderClasses = [__styles.loading]
|
||||
|
||||
// custom button tag
|
||||
const CustomButton = ({ ...props }) => {
|
||||
const Tag = as as keyof JSX.IntrinsicElements
|
||||
return <Tag {...props} />
|
||||
}
|
||||
|
||||
const buttonContent = (
|
||||
<>
|
||||
{showIcon &&
|
||||
(loading ? (
|
||||
<IconLoader size={size} className={iconLoaderClasses.join(' ')} />
|
||||
) : icon ? (
|
||||
<IconContext.Provider value={{ contextSize: size }}>{icon}</IconContext.Provider>
|
||||
) : null)}
|
||||
{children && <span className={__styles.label}>{children}</span>}
|
||||
{iconRight && !loading && (
|
||||
<IconContext.Provider value={{ contextSize: size }}>{iconRight}</IconContext.Provider>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
||||
if (as) {
|
||||
return (
|
||||
<CustomButton {...props} className={classes.join(' ')} onClick={onClick} style={style}>
|
||||
{buttonContent}
|
||||
</CustomButton>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
// <span ref={containerRef} className={containerClasses.join(' ')}>
|
||||
<button
|
||||
{...props}
|
||||
ref={buttonRef}
|
||||
className={classes.join(' ')}
|
||||
disabled={loading || (disabled && true)}
|
||||
onClick={onClick}
|
||||
style={style}
|
||||
type={htmlType}
|
||||
aria-selected={ariaSelected}
|
||||
aria-controls={ariaControls}
|
||||
tabIndex={tabIndex}
|
||||
role={role}
|
||||
form={props.form}
|
||||
>
|
||||
{buttonContent}
|
||||
</button>
|
||||
// </span>
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
export * from './Button'
|
||||
@@ -0,0 +1,27 @@
|
||||
.sbui-card {
|
||||
@apply flex flex-col bg-white dark:bg-dark-700 rounded-md shadow-lg overflow-hidden relative;
|
||||
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.sbui-card--hoverable {
|
||||
@apply transition transform hover:-translate-y-1 hover:shadow-2xl;
|
||||
}
|
||||
|
||||
.dark .sbui-card {
|
||||
border: 1px solid #2a2a2a;
|
||||
}
|
||||
|
||||
.sbui-card-head {
|
||||
@apply px-8 py-6 flex justify-between;
|
||||
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.dark .sbui-card-head {
|
||||
border-bottom: 1px solid #2a2a2a;
|
||||
}
|
||||
|
||||
.sbui-card-content {
|
||||
@apply p-8;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import React from 'react'
|
||||
import Typography from '../Typography'
|
||||
// import { AutoForm } from 'uniforms'
|
||||
|
||||
import { Card } from './'
|
||||
|
||||
export default {
|
||||
title: 'Displays/Card',
|
||||
component: Card,
|
||||
}
|
||||
|
||||
export const Default = (args: any) => (
|
||||
<Card {...args}>
|
||||
<Typography.Title level={5}>Card content</Typography.Title>
|
||||
<Typography.Title level={5}>Card content</Typography.Title>
|
||||
<Typography.Title level={5}>Card content</Typography.Title>
|
||||
</Card>
|
||||
)
|
||||
|
||||
export const withCover = (args: any) => (
|
||||
<Card {...args}>
|
||||
<Typography.Text type="secondary">Sub title here</Typography.Text>
|
||||
<Typography.Title level={3}>To Do List with Vue.JS</Typography.Title>
|
||||
</Card>
|
||||
)
|
||||
|
||||
export const withMeta = (args: any) => (
|
||||
<Card {...args}>
|
||||
<Card.Meta title={'To Do List with Vue.JS'} description={'To Do List with Vue.JS'}/>
|
||||
</Card>
|
||||
)
|
||||
|
||||
export const withHover = (args: any) => (
|
||||
<Card {...args}>
|
||||
<Card.Meta title={'To Do List with Vue.JS'} description={'To Do List with Vue.JS'}/>
|
||||
</Card>
|
||||
)
|
||||
|
||||
Default.args = {
|
||||
title: 'I am a title',
|
||||
titleExtra: <Typography.Link>Learn more</Typography.Link>,
|
||||
}
|
||||
|
||||
withCover.args = {
|
||||
cover: (
|
||||
<img
|
||||
className="h-64 w-full object-cover"
|
||||
src={'https://supabase.io/new/images/case-study-monitoro.jpg'}
|
||||
alt={'title'}
|
||||
/>
|
||||
),
|
||||
}
|
||||
|
||||
withMeta.args = {
|
||||
title: 'title is here'
|
||||
}
|
||||
|
||||
withHover.args = {
|
||||
title: 'This card can hover',
|
||||
hoverable: true
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import React from 'react'
|
||||
import Typography from '../Typography'
|
||||
// @ts-ignore
|
||||
import CardStyles from './Card.module.css'
|
||||
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
|
||||
interface CardProps {
|
||||
children?: React.ReactNode
|
||||
className?: string
|
||||
cover?: React.ReactNode
|
||||
description?: string
|
||||
hoverable?: boolean
|
||||
style?: React.CSSProperties
|
||||
title?: string
|
||||
titleExtra?: React.ReactNode
|
||||
}
|
||||
|
||||
function Card({
|
||||
children,
|
||||
className,
|
||||
cover,
|
||||
hoverable,
|
||||
style,
|
||||
title,
|
||||
titleExtra,
|
||||
}: CardProps) {
|
||||
let __styles = styleHandler('card')
|
||||
|
||||
let classes = [__styles.base]
|
||||
if (hoverable) classes.push(__styles.hoverable)
|
||||
if (className) classes.push(className)
|
||||
|
||||
return (
|
||||
<div className={classes.join(' ')} style={style}>
|
||||
{title && (
|
||||
<div className={__styles.head}>
|
||||
<Typography.Text style={{ margin: 0 }}>{title}</Typography.Text>
|
||||
<Typography.Link style={{ margin: 0 }}>{titleExtra}</Typography.Link>
|
||||
</div>
|
||||
)}
|
||||
{cover}
|
||||
<div className={__styles.content}>{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface MetaProps {
|
||||
title?: string
|
||||
description?: string
|
||||
style?: React.CSSProperties
|
||||
className?: string
|
||||
}
|
||||
|
||||
function Meta({ title, description, style, className }: MetaProps) {
|
||||
return (
|
||||
<div style={style} className={className}>
|
||||
<Typography.Title style={{ margin: '0' }} level={5}>
|
||||
{title}
|
||||
</Typography.Title>
|
||||
<div>
|
||||
<Typography.Text type="secondary">{description}</Typography.Text>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Card.Meta = Meta
|
||||
export default Card
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Card } from './Card'
|
||||
@@ -0,0 +1,127 @@
|
||||
/* clear native styling */
|
||||
/* .sbui-checkbox[type='checkbox'] {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
padding: 0;
|
||||
-webkit-print-color-adjust: exact;
|
||||
color-adjust: exact;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
background-origin: border-box;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
flex-shrink: 0;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
color: #2563eb;
|
||||
background-color: #fff;
|
||||
border-color: #6b7280;
|
||||
border-width: 1px;
|
||||
} */
|
||||
|
||||
/* .sbui-checkbox[type='checkbox']:checked {
|
||||
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
.sbui-checkbox[type='checkbox']:checked {
|
||||
@apply dark:bg-brand-700;
|
||||
@apply bg-brand-700;
|
||||
border-color: transparent;
|
||||
background-size: 100% 100%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
} */
|
||||
|
||||
/* .sbui-checkbox {
|
||||
@apply border border-solid rounded;
|
||||
|
||||
@apply text-brand-700 border-gray-300 transition-all;
|
||||
@apply hover:border-brand-500 focus:ring-brand-500 focus:outline-none;
|
||||
|
||||
@apply dark:bg-transparent dark:border-dark-400 dark:text-white;
|
||||
@apply dark:hover:border-brand-500;
|
||||
|
||||
margin-top: 2px;
|
||||
} */
|
||||
/*
|
||||
.sbui-checkbox-container {
|
||||
@apply flex cursor-pointer;
|
||||
} */
|
||||
|
||||
/* .sbui-checkbox__label-container {
|
||||
@apply leading-none;
|
||||
} */
|
||||
|
||||
/* .sbui-checkbox__label-container__label {
|
||||
@apply text-gray-700 dark:text-white cursor-pointer mt-0;
|
||||
}
|
||||
|
||||
.sbui-checkbox__label-container__label__span {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
.sbui-checkbox__label-container__label__span .sbui-checkbox__label-text-before,
|
||||
.sbui-checkbox__label-container__label__span .sbui-checkbox__label-text-after {
|
||||
@apply text-gray-400 dark:text-gray-300;
|
||||
}
|
||||
|
||||
.sbui-checkbox__label-container__label__p {
|
||||
@apply mt-0 text-gray-400 dark:text-gray-300;
|
||||
} */
|
||||
|
||||
/*
|
||||
Label sizes
|
||||
*/
|
||||
|
||||
/* .sbui-checkbox-container--tiny .sbui-checkbox__label-container__label,
|
||||
.sbui-checkbox-container--tiny .sbui-checkbox__label-container__label__span,
|
||||
.sbui-checkbox-container--tiny .sbui-checkbox__label-container__label__p {
|
||||
@apply text-xs;
|
||||
}
|
||||
.sbui-checkbox-container--small .sbui-checkbox__label-container__label,
|
||||
.sbui-checkbox-container--small .sbui-checkbox__label-container__label__span,
|
||||
.sbui-checkbox-container--small .sbui-checkbox__label-container__label__p {
|
||||
@apply text-sm;
|
||||
}
|
||||
.sbui-checkbox-container--medium .sbui-checkbox__label-container__label,
|
||||
.sbui-checkbox-container--medium .sbui-checkbox__label-container__label__span,
|
||||
.sbui-checkbox-container--medium .sbui-checkbox__label-container__label__p {
|
||||
@apply text-sm;
|
||||
}
|
||||
.sbui-checkbox-container--large .sbui-checkbox__label-container__label,
|
||||
.sbui-checkbox-container--large .sbui-checkbox__label-container__label__span,
|
||||
.sbui-checkbox-container--large .sbui-checkbox__label-container__label__p {
|
||||
@apply text-base;
|
||||
}
|
||||
.sbui-checkbox-container--xlarge .sbui-checkbox__label-container__label,
|
||||
.sbui-checkbox-container--xlarge .sbui-checkbox__label-container__label__span,
|
||||
.sbui-checkbox-container--xlarge .sbui-checkbox__label-container__label__p {
|
||||
@apply text-base;
|
||||
} */
|
||||
|
||||
/*
|
||||
Checkbox sizes
|
||||
*/
|
||||
|
||||
/* .sbui-checkbox-container--tiny .sbui-checkbox {
|
||||
@apply h-3 w-3 mt-1 mr-3;
|
||||
}
|
||||
|
||||
.sbui-checkbox-container--small .sbui-checkbox {
|
||||
@apply h-3.5 w-3.5 mt-0.5 mr-3.5;
|
||||
}
|
||||
|
||||
.sbui-checkbox-container--medium .sbui-checkbox {
|
||||
@apply h-4 w-4 mt-0.5 mr-3.5;
|
||||
}
|
||||
|
||||
.sbui-checkbox-container--large .sbui-checkbox {
|
||||
@apply h-5 w-5 mt-0.5 mr-4;
|
||||
}
|
||||
|
||||
.sbui-checkbox-container--xlarge .sbui-checkbox {
|
||||
@apply h-5 w-5 mt-0.5 mr-4;
|
||||
} */
|
||||
@@ -0,0 +1,133 @@
|
||||
import React from 'react'
|
||||
|
||||
import { Checkbox } from '.'
|
||||
|
||||
export default {
|
||||
title: 'Data Input/Checkbox',
|
||||
component: Checkbox,
|
||||
}
|
||||
|
||||
export const Default = (args: any) => <Checkbox {...args} />
|
||||
|
||||
export const withGroup = (args: any) => (
|
||||
<Checkbox.Group {...args}>
|
||||
<Checkbox
|
||||
id="checkbox1"
|
||||
name="checkbox1"
|
||||
label="JavaScript"
|
||||
description="JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification."
|
||||
/>
|
||||
<Checkbox
|
||||
id="checkbox2"
|
||||
name="checkbox2"
|
||||
label="Typescript"
|
||||
description="TypeScript is a programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript and adds optional static typing to the language. "
|
||||
/>
|
||||
<Checkbox
|
||||
id="checkbox3"
|
||||
name="checkbox3"
|
||||
label="React"
|
||||
description="React is an open-source, front end, JavaScript library for building user interfaces or UI components. It is maintained by Facebook and a community of individual developers and companies."
|
||||
/>
|
||||
</Checkbox.Group>
|
||||
)
|
||||
|
||||
export const withGroupHorizontal = (args: any) => (
|
||||
<Checkbox.Group {...args}>
|
||||
<Checkbox
|
||||
id="checkbox1"
|
||||
name="checkbox1"
|
||||
label="JavaScript"
|
||||
description="JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification."
|
||||
/>
|
||||
<Checkbox
|
||||
id="checkbox2"
|
||||
name="checkbox2"
|
||||
label="Typescript"
|
||||
description="TypeScript is a programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript and adds optional static typing to the language. "
|
||||
/>
|
||||
<Checkbox
|
||||
id="checkbox3"
|
||||
name="checkbox3"
|
||||
label="React"
|
||||
description="React is an open-source, front end, JavaScript library for building user interfaces or UI components. It is maintained by Facebook and a community of individual developers and companies."
|
||||
/>
|
||||
</Checkbox.Group>
|
||||
)
|
||||
|
||||
export const size = (args: any) => (
|
||||
<Checkbox.Group {...args}>
|
||||
<Checkbox
|
||||
id="checkbox1"
|
||||
name="checkbox1"
|
||||
label="JavaScript"
|
||||
description="JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification."
|
||||
/>
|
||||
<Checkbox
|
||||
id="checkbox2"
|
||||
name="checkbox2"
|
||||
label="Typescript"
|
||||
description="TypeScript is a programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript and adds optional static typing to the language. "
|
||||
/>
|
||||
<Checkbox
|
||||
id="checkbox3"
|
||||
name="checkbox3"
|
||||
label="React"
|
||||
description="React is an open-source, front end, JavaScript library for building user interfaces or UI components. It is maintained by Facebook and a community of individual developers and companies."
|
||||
/>
|
||||
</Checkbox.Group>
|
||||
)
|
||||
|
||||
export const withBeforeAndAfterLabels = (args: any) => (
|
||||
<Checkbox.Group {...args} />
|
||||
)
|
||||
|
||||
Default.args = {
|
||||
label: 'This is the label',
|
||||
description: 'This is the description',
|
||||
}
|
||||
|
||||
withGroup.args = {
|
||||
id: 'checkobox-q',
|
||||
label: 'This is the label',
|
||||
description: 'This is the description',
|
||||
disabled: false,
|
||||
size: 'medium',
|
||||
className: 'font-sans',
|
||||
layout: 'vertical',
|
||||
}
|
||||
|
||||
withGroupHorizontal.args = {
|
||||
id: 'checkobox-q',
|
||||
label: 'This is the label',
|
||||
description: 'This is the description',
|
||||
disabled: false,
|
||||
className: 'font-sans',
|
||||
layout: 'horizontal',
|
||||
}
|
||||
|
||||
size.args = {
|
||||
id: 'checkobox-q',
|
||||
label: 'Control the size of the checkboxes',
|
||||
description:
|
||||
'You can add a size just the Group component and it will affect the children',
|
||||
disabled: false,
|
||||
className: 'font-sans',
|
||||
layout: 'horizontal',
|
||||
size: 'tiny',
|
||||
}
|
||||
|
||||
withBeforeAndAfterLabels.args = {
|
||||
label: 'Label',
|
||||
beforeLabel: 'Before : ',
|
||||
afterLabel: ' : After',
|
||||
options: [
|
||||
{
|
||||
label: 'Label',
|
||||
beforeLabel: 'Before : ',
|
||||
afterLabel: ' : After',
|
||||
description: 'Description',
|
||||
},
|
||||
],
|
||||
className: 'font-sans',
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import Checkbox from './Checkbox'
|
||||
|
||||
describe('#Checkbox', () => {
|
||||
it('should render checkbox correctly', () => {
|
||||
render(<Checkbox data-testid="form-checkbox" label="labelIsRequired" />)
|
||||
expect(screen.queryByTestId('form-checkbox')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should show label', () => {
|
||||
render(<Checkbox data-testid="form-checkbox" label="JavaScript" />)
|
||||
expect(screen.queryByText('JavaScript')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,216 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { FormLayout } from '../../lib/Layout/FormLayout'
|
||||
import { CheckboxContext } from './CheckboxContext'
|
||||
// @ts-ignore
|
||||
import CheckboxStyles from './Checkbox.module.css'
|
||||
|
||||
import defaultTheme from '../../lib/theme/defaultTheme'
|
||||
|
||||
import { useFormContext } from '../Form/FormContext'
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
|
||||
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
|
||||
afterLabel?: string
|
||||
beforeLabel?: string
|
||||
description?: string
|
||||
label?: string
|
||||
size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge'
|
||||
}
|
||||
|
||||
interface GroupProps {
|
||||
id?: string
|
||||
layout?: 'horizontal' | 'vertical'
|
||||
error?: any
|
||||
descriptionText?: any
|
||||
label?: any
|
||||
afterLabel?: string
|
||||
beforeLabel?: string
|
||||
labelOptional?: any
|
||||
name?: any
|
||||
value?: any
|
||||
className?: string
|
||||
children?: React.ReactNode
|
||||
options?: Array<InputProps>
|
||||
defaultValue?: string
|
||||
onChange?(x: React.ChangeEvent<HTMLInputElement>): void
|
||||
size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge'
|
||||
}
|
||||
|
||||
function Group({
|
||||
id,
|
||||
layout = 'vertical',
|
||||
error,
|
||||
descriptionText,
|
||||
label,
|
||||
afterLabel,
|
||||
beforeLabel,
|
||||
labelOptional,
|
||||
children,
|
||||
className,
|
||||
options,
|
||||
onChange,
|
||||
size = 'medium',
|
||||
}: GroupProps) {
|
||||
const parentCallback = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (onChange) onChange(e)
|
||||
}
|
||||
|
||||
const __styles = styleHandler('checkbox')
|
||||
|
||||
return (
|
||||
<FormLayout
|
||||
label={label}
|
||||
afterLabel={afterLabel}
|
||||
beforeLabel={beforeLabel}
|
||||
labelOptional={labelOptional}
|
||||
layout={layout}
|
||||
id={id}
|
||||
error={error}
|
||||
descriptionText={descriptionText}
|
||||
className={className}
|
||||
size={size}
|
||||
>
|
||||
<CheckboxContext.Provider value={{ parentCallback, parentSize: size }}>
|
||||
<div className={__styles.group}>
|
||||
{options
|
||||
? options.map((option: InputProps) => {
|
||||
return (
|
||||
<Checkbox
|
||||
id={option.id}
|
||||
value={option.value}
|
||||
label={option.label}
|
||||
beforeLabel={option.beforeLabel}
|
||||
afterLabel={option.afterLabel}
|
||||
checked={option.checked}
|
||||
name={option.name}
|
||||
description={option.description}
|
||||
/>
|
||||
)
|
||||
})
|
||||
: children}
|
||||
</div>
|
||||
</CheckboxContext.Provider>
|
||||
</FormLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export function Checkbox({
|
||||
className,
|
||||
id = '',
|
||||
name = '',
|
||||
label,
|
||||
afterLabel,
|
||||
beforeLabel,
|
||||
description,
|
||||
checked,
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
size = 'medium',
|
||||
disabled = false,
|
||||
...props
|
||||
}: InputProps) {
|
||||
const { formContextOnChange, values, handleBlur } = useFormContext()
|
||||
|
||||
const __styles = styleHandler('checkbox')
|
||||
|
||||
return (
|
||||
<CheckboxContext.Consumer>
|
||||
{({ parentCallback, parentSize }) => {
|
||||
// if id does not exist, use label
|
||||
const markupId = id
|
||||
? id
|
||||
: name
|
||||
? name
|
||||
: label
|
||||
? label
|
||||
.toLowerCase()
|
||||
.replace(/^[^A-Z0-9]+/gi, '')
|
||||
.replace(/ /g, '-')
|
||||
: undefined
|
||||
|
||||
// @ts-ignore
|
||||
size = parentSize ? parentSize : size
|
||||
|
||||
// if name does not exist on Radio then use Context Name from Radio.Group
|
||||
// if that fails, use the id
|
||||
const markupName = name ? name : markupId
|
||||
|
||||
// check if checkbox checked is true or false
|
||||
// if neither true or false the checkbox will rely on native control
|
||||
let active = checked ?? undefined
|
||||
|
||||
// if (values && !value) value = values[id || name]
|
||||
|
||||
let containerClasses = [__styles.container]
|
||||
|
||||
function onInputChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
// '`onChange` callback for parent component
|
||||
if (parentCallback) parentCallback(e)
|
||||
// '`onChange` callback for this component
|
||||
if (onChange) onChange(e)
|
||||
// update form
|
||||
if (formContextOnChange) formContextOnChange(e)
|
||||
}
|
||||
|
||||
if (className) containerClasses.push(className)
|
||||
|
||||
if (values && checked === undefined) active = values[id || name]
|
||||
|
||||
function handleBlurEvent(e: React.FocusEvent<HTMLInputElement>) {
|
||||
if (handleBlur) handleBlur(e)
|
||||
if (onBlur) onBlur(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={containerClasses.join(' ')}>
|
||||
<input
|
||||
id={markupId}
|
||||
name={markupName}
|
||||
type="checkbox"
|
||||
className={[__styles.base, __styles.size[size]].join(' ')}
|
||||
onChange={onInputChange}
|
||||
onBlur={handleBlurEvent}
|
||||
checked={active}
|
||||
value={value ? value : markupId}
|
||||
disabled={disabled}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
<label
|
||||
className={[__styles.label.base, __styles.label[size]].join(' ')}
|
||||
htmlFor={markupId}
|
||||
>
|
||||
<span>
|
||||
{beforeLabel && (
|
||||
<span
|
||||
className={[__styles.label_before.base, __styles.label_before[size]].join(' ')}
|
||||
>
|
||||
{beforeLabel}
|
||||
</span>
|
||||
)}
|
||||
{label}
|
||||
{afterLabel && (
|
||||
<span
|
||||
className={[__styles.label_after.base, __styles.label_after[size]].join(' ')}
|
||||
>
|
||||
{afterLabel}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
|
||||
{description && (
|
||||
<p className={[__styles.description.base, __styles.description[size]].join(' ')}>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</CheckboxContext.Consumer>
|
||||
)
|
||||
}
|
||||
|
||||
Checkbox.Group = Group
|
||||
export default Checkbox
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createContext } from 'react'
|
||||
|
||||
// Make sure the shape of the default value passed to
|
||||
// createContext matches the shape that the consumers expect!
|
||||
export const CheckboxContext = createContext({
|
||||
parentCallback: (e: any) => {},
|
||||
parentSize: '',
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
import Checkbox from './Checkbox'
|
||||
export default Checkbox
|
||||
export { default as Checkbox } from './Checkbox'
|
||||
@@ -0,0 +1,67 @@
|
||||
import React from 'react'
|
||||
// import { AutoForm } from 'uniforms'
|
||||
|
||||
import { Collapsible } from '.'
|
||||
import { IconChevronUp } from '../..'
|
||||
import { Button } from '../Button'
|
||||
|
||||
export default {
|
||||
title: 'Displays/Collapsible',
|
||||
component: Collapsible,
|
||||
}
|
||||
|
||||
export const Default = (args: any) => {
|
||||
return (
|
||||
<>
|
||||
hello all
|
||||
<Collapsible className="-space-y-px">
|
||||
<Collapsible.Trigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="group text-scale-1200 flex justify-between items-center w-full bg-scale-300 rounded border border-scale-500 p-3"
|
||||
>
|
||||
Hello
|
||||
<div className="flex gap-2 items-center">
|
||||
<IconChevronUp className="transition data-open-parent:rotate-0 data-closed-parent:rotate-180" />
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
}}
|
||||
>
|
||||
Turn it on
|
||||
</Button>
|
||||
</div>
|
||||
</button>
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Content>
|
||||
<div className="group text-scale-1200 flex justify-between items-center w-full bg-scale-300 rounded border border-scale-500 p-3">
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
</div>
|
||||
</Collapsible.Content>
|
||||
</Collapsible>
|
||||
<Collapsible>
|
||||
<Collapsible.Trigger asChild>
|
||||
<button type="button">Hello</button>
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Content>
|
||||
<div>
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
<h3 className="text-tomato-900">I am content</h3>
|
||||
</div>
|
||||
</Collapsible.Content>
|
||||
</Collapsible>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Default.args = {
|
||||
placeholder: 'Type text here ...',
|
||||
disabled: false,
|
||||
label: 'Name',
|
||||
layout: 'vertical',
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import * as RadixCollapsible from '@radix-ui/react-collapsible'
|
||||
import React from 'react'
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
|
||||
export interface CollapsibleProps extends RadixCollapsible.CollapsibleProps {
|
||||
children: React.ReactNode
|
||||
// onChange?: (e: boolean) => void
|
||||
}
|
||||
|
||||
export const Collapsible = ({
|
||||
open = undefined,
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: CollapsibleProps) => {
|
||||
// const [_open, setOpen] = React.useState(open)
|
||||
|
||||
// function handleOpenChange(e: boolean) {
|
||||
// console.log(e)
|
||||
// if (onChange) onChange(e)
|
||||
// }
|
||||
return (
|
||||
<RadixCollapsible.Root
|
||||
defaultOpen={props.defaultOpen}
|
||||
open={open}
|
||||
onOpenChange={props.onOpenChange}
|
||||
disabled={props.disabled}
|
||||
className={className}
|
||||
>
|
||||
{children}
|
||||
</RadixCollapsible.Root>
|
||||
)
|
||||
}
|
||||
|
||||
export function Trigger({ children, asChild }: { children: React.ReactNode; asChild?: boolean }) {
|
||||
return <RadixCollapsible.Trigger asChild={asChild}>{children}</RadixCollapsible.Trigger>
|
||||
}
|
||||
|
||||
export function Content({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
}) {
|
||||
const __styles = styleHandler('collapsible')
|
||||
return (
|
||||
<RadixCollapsible.Content className={[__styles.content, className].join(' ')}>
|
||||
{children}
|
||||
</RadixCollapsible.Content>
|
||||
)
|
||||
}
|
||||
|
||||
Collapsible.Trigger = Trigger
|
||||
Collapsible.Content = Content
|
||||
export default Collapsible
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Collapsible } from './Collapsible'
|
||||
@@ -0,0 +1,65 @@
|
||||
.sbui-contextmenu-item {
|
||||
@apply text-xs;
|
||||
@apply text-typography-body-light dark:text-typography-body-dark;
|
||||
@apply px-4 py-1.5 flex items-center space-x-2;
|
||||
@apply cursor-pointer;
|
||||
@apply focus:bg-bg-secondary-light dark:focus:bg-bg-primary-dark border-none;
|
||||
cursor: 'default';
|
||||
}
|
||||
|
||||
.sbui-contextmenu-item svg {
|
||||
/* @apply text-typography-body-secondary-light dark:text-typography-body-secondary-dark; */
|
||||
}
|
||||
|
||||
.sbui-contextmenu-label {
|
||||
/* @apply text-typography-body-secondary-light dark:text-typography-body-secondary-dark; */
|
||||
/* @apply px-4 py-1.5 flex items-center space-x-2; */
|
||||
/* font-size: 0.65rem; */
|
||||
}
|
||||
|
||||
.sbui-contextmenu-misc {
|
||||
/* @apply px-4 py-1.5; */
|
||||
}
|
||||
|
||||
.sbui-contextmenu-item:focus-visible {
|
||||
/* border: none; */
|
||||
/* outline: none; */
|
||||
}
|
||||
|
||||
.sbui-contextmenu-input {
|
||||
/* @apply flex items-center space-x-2; */
|
||||
}
|
||||
|
||||
.sbui-contextmenu-input__check {
|
||||
/* @apply flex items-center; */
|
||||
}
|
||||
|
||||
.sbui-contextmenu__content {
|
||||
/* @apply bg-bg-primary-light dark:bg-bg-secondary-dark p-0; */
|
||||
/* @apply rounded; */
|
||||
/* @apply border; */
|
||||
/* @apply shadow; */
|
||||
/* overflow: visible; */
|
||||
/* border-style: solid; */
|
||||
/* border-width: 1px; */
|
||||
}
|
||||
|
||||
@keyframes transition {
|
||||
/* 0% { */
|
||||
/* opacity: 0; */
|
||||
/* transform: scale(0.95); */
|
||||
/* } */
|
||||
/* 100% { */
|
||||
/* opacity: 1; */
|
||||
/* transform: scale(1); */
|
||||
/* } */
|
||||
}
|
||||
|
||||
.sbui-contextmenu__content {
|
||||
/* transform-origin: var(--radix-dropdown-menu-content-transform-origin); */
|
||||
/* animation: transition 0.1s ease-out; */
|
||||
}
|
||||
|
||||
.sbui-contextmenu__trigger {
|
||||
/* @apply border-none bg-transparent p-0 focus:ring-0; */
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Button } from '../Button'
|
||||
import { Divider } from '../Divider'
|
||||
import { IconSettings, IconLogOut } from '../../index'
|
||||
import Typography from '../Typography'
|
||||
|
||||
import { ContextMenu } from '.'
|
||||
import { IconLogIn } from '../Icon/icons/IconLogIn'
|
||||
|
||||
export default {
|
||||
title: 'Navigation/ContextMenu',
|
||||
component: ContextMenu,
|
||||
}
|
||||
|
||||
const triggerArea = (
|
||||
<div
|
||||
style={{
|
||||
background: 'gray',
|
||||
width: '280px',
|
||||
height: '180px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<span>Right click this area</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
export const Default = (args: any) => (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<ContextMenu
|
||||
{...args}
|
||||
overlay={[
|
||||
<ContextMenu.Misc>
|
||||
<div>
|
||||
<Typography.Text small className="block">
|
||||
Signed in as{' '}
|
||||
</Typography.Text>
|
||||
|
||||
<Typography.Text small strong>
|
||||
tom@example.com{' '}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</ContextMenu.Misc>,
|
||||
<Divider light />,
|
||||
<ContextMenu.Label>Group label</ContextMenu.Label>,
|
||||
<ContextMenu.Item onClick={() => console.log('clicked')}>
|
||||
Account
|
||||
</ContextMenu.Item>,
|
||||
<ContextMenu.Item>Settings</ContextMenu.Item>,
|
||||
<Divider light />,
|
||||
<ContextMenu.Item icon={<IconLogIn size="tiny" />}>
|
||||
Log out
|
||||
</ContextMenu.Item>,
|
||||
]}
|
||||
>
|
||||
{triggerArea}
|
||||
</ContextMenu>
|
||||
</div>
|
||||
)
|
||||
|
||||
Default.args = {}
|
||||
|
||||
export const doNotcloseOverlay = (args: any) => (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<ContextMenu
|
||||
{...args}
|
||||
overlay={[
|
||||
<ContextMenu.Misc>
|
||||
<Typography.Text>Signed in as </Typography.Text>
|
||||
<Typography.Text strong>tom@example.com </Typography.Text>
|
||||
</ContextMenu.Misc>,
|
||||
<Divider light />,
|
||||
<ContextMenu.Item>Account</ContextMenu.Item>,
|
||||
<ContextMenu.Item>Settings</ContextMenu.Item>,
|
||||
<ContextMenu.Item>
|
||||
<Button icon={<IconLogOut />}>Log out</Button>
|
||||
</ContextMenu.Item>,
|
||||
]}
|
||||
>
|
||||
{triggerArea}
|
||||
</ContextMenu>
|
||||
</div>
|
||||
)
|
||||
|
||||
doNotcloseOverlay.args = {}
|
||||
|
||||
export const withCustomStyles = (args: any) => (
|
||||
<div
|
||||
style={{
|
||||
margin: '0 auto',
|
||||
minHeight: '420px',
|
||||
marginTop: '220px',
|
||||
marginLeft: '400px',
|
||||
}}
|
||||
>
|
||||
<ContextMenu
|
||||
overlayStyle={{ minWidth: '500px' }}
|
||||
placement="bottomRight"
|
||||
{...args}
|
||||
overlay={[
|
||||
<ContextMenu.Item>
|
||||
<Typography.Text>Signed in as </Typography.Text>
|
||||
<Typography.Text strong>tom@example.com </Typography.Text>
|
||||
</ContextMenu.Item>,
|
||||
<Divider light />,
|
||||
<ContextMenu.Item>Account</ContextMenu.Item>,
|
||||
<ContextMenu.Item>Settings</ContextMenu.Item>,
|
||||
<Divider light />,
|
||||
<ContextMenu.Item>
|
||||
<Button type="default" icon={<IconLogOut />}>
|
||||
Log out
|
||||
</Button>
|
||||
</ContextMenu.Item>,
|
||||
]}
|
||||
>
|
||||
{triggerArea}
|
||||
</ContextMenu>
|
||||
</div>
|
||||
)
|
||||
|
||||
withCustomStyles.args = {}
|
||||
|
||||
export const Checkbox = (args: any) => {
|
||||
const [checked, setChecked] = useState(false)
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<ContextMenu
|
||||
{...args}
|
||||
overlay={[
|
||||
<ContextMenu.Item icon={<IconSettings size="small" />}>
|
||||
Account
|
||||
</ContextMenu.Item>,
|
||||
<ContextMenu.Item>Settings</ContextMenu.Item>,
|
||||
<Divider light />,
|
||||
<ContextMenu.Checkbox checked={checked} onChange={setChecked}>
|
||||
Show subtitles
|
||||
</ContextMenu.Checkbox>,
|
||||
]}
|
||||
>
|
||||
{triggerArea}
|
||||
</ContextMenu>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const Radio = (args: any) => {
|
||||
const [value, setValue] = useState('red')
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<ContextMenu
|
||||
{...args}
|
||||
overlay={[
|
||||
<ContextMenu.RadioGroup value={value} onChange={setValue}>
|
||||
<ContextMenu.Radio value={'red'}>Red</ContextMenu.Radio>
|
||||
<ContextMenu.Radio value={'blue'}>Blue</ContextMenu.Radio>
|
||||
<ContextMenu.Radio value={'green'}>Green</ContextMenu.Radio>
|
||||
</ContextMenu.RadioGroup>,
|
||||
]}
|
||||
>
|
||||
{triggerArea}
|
||||
</ContextMenu>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
// import * as RadixContextMenu from '@radix-ui/react-dropdown-menu'
|
||||
import { IconCheck } from '../Icon/icons/IconCheck'
|
||||
|
||||
// @ts-ignore
|
||||
// import ContextMenuStyles from './ContextMenu.module.css'
|
||||
|
||||
import type * as RadixContextMenuTypes from '@radix-ui/react-context-menu/'
|
||||
|
||||
import * as RadixContextMenu from '@radix-ui/react-context-menu'
|
||||
|
||||
const ContextMenuStyles = {}
|
||||
|
||||
interface RootProps {
|
||||
onOpenChange?(x: boolean): void
|
||||
alignOffset?: RadixContextMenuTypes.ContextMenuContentProps['alignOffset']
|
||||
overlay?: React.ReactNode
|
||||
children?: React.ReactNode
|
||||
className?: string
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
function ContextMenu({
|
||||
onOpenChange,
|
||||
|
||||
alignOffset = 6,
|
||||
overlay,
|
||||
children,
|
||||
className,
|
||||
style,
|
||||
}: RootProps) {
|
||||
// let classes = [ContextMenuStyles['sbui-contextmenu__content']]
|
||||
// if (className) {
|
||||
// classes.push(className)
|
||||
// }
|
||||
return (
|
||||
<RadixContextMenu.Root onOpenChange={onOpenChange}>
|
||||
<RadixContextMenu.Trigger
|
||||
// className={ContextMenuStyles['sbui-contextmenu__trigger']}
|
||||
>
|
||||
{children}
|
||||
</RadixContextMenu.Trigger>
|
||||
|
||||
<RadixContextMenu.Content
|
||||
sideOffset={alignOffset}
|
||||
// className={classes.join(' ')}
|
||||
style={style}
|
||||
>
|
||||
{overlay}
|
||||
</RadixContextMenu.Content>
|
||||
</RadixContextMenu.Root>
|
||||
)
|
||||
}
|
||||
|
||||
interface ItemProps {
|
||||
children: React.ReactNode
|
||||
icon?: React.ReactNode
|
||||
disabled?: boolean
|
||||
onClick?: (event: Event) => void
|
||||
}
|
||||
|
||||
export function Item({ children, icon, disabled, onClick }: ItemProps) {
|
||||
return (
|
||||
<RadixContextMenu.Item
|
||||
// className={ContextMenuStyles['sbui-contextmenu-item']}
|
||||
disabled={disabled}
|
||||
onSelect={onClick}
|
||||
>
|
||||
{icon && icon}
|
||||
<span>{children}</span>
|
||||
</RadixContextMenu.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export function Misc({ children, icon }: ItemProps) {
|
||||
return (
|
||||
<div
|
||||
// className={ContextMenuStyles['sbui-contextmenu-misc']}
|
||||
>
|
||||
{icon && icon}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface CheckboxProps {
|
||||
children: React.ReactNode
|
||||
checked?: boolean
|
||||
onChange?(x: boolean): void
|
||||
disabled?: boolean
|
||||
ItemIndicator?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Checkbox({
|
||||
children,
|
||||
checked: propsChecked,
|
||||
onChange,
|
||||
disabled,
|
||||
ItemIndicator,
|
||||
}: CheckboxProps) {
|
||||
const [checked, setChecked] = useState(propsChecked ? propsChecked : false)
|
||||
|
||||
const handleChange = (e: boolean) => {
|
||||
if (onChange) onChange(e)
|
||||
setChecked(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<RadixContextMenu.CheckboxItem
|
||||
checked={checked}
|
||||
onCheckedChange={handleChange}
|
||||
// className={`${ContextMenuStyles['sbui-contextmenu-item']} ${ContextMenuStyles['sbui-contextmenu-input']}`}
|
||||
disabled={disabled}
|
||||
>
|
||||
<RadixContextMenu.ItemIndicator
|
||||
// className={ContextMenuStyles['sbui-contextmenu-input__check']}
|
||||
>
|
||||
{ItemIndicator ? ItemIndicator : <IconCheck size="tiny" />}
|
||||
<RadixContextMenu.CheckboxItem />
|
||||
</RadixContextMenu.ItemIndicator>
|
||||
<span>{children}</span>
|
||||
</RadixContextMenu.CheckboxItem>
|
||||
)
|
||||
}
|
||||
|
||||
interface RadioProps {
|
||||
children: React.ReactNode
|
||||
value: string
|
||||
ItemIndicator?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Radio({ children, value, ItemIndicator }: RadioProps) {
|
||||
return (
|
||||
<RadixContextMenu.RadioItem
|
||||
value={value}
|
||||
// className={`${ContextMenuStyles['sbui-contextmenu-item']} ${ContextMenuStyles['sbui-contextmenu-input']}`}
|
||||
>
|
||||
<RadixContextMenu.ItemIndicator
|
||||
// className={ContextMenuStyles['sbui-contextmenu-input__check']}
|
||||
>
|
||||
{ItemIndicator ? ItemIndicator : <IconCheck size="tiny" />}
|
||||
</RadixContextMenu.ItemIndicator>
|
||||
<span>{children}</span>
|
||||
</RadixContextMenu.RadioItem>
|
||||
)
|
||||
}
|
||||
|
||||
interface RadioGroupProps {
|
||||
children: React.ReactNode
|
||||
value: string
|
||||
onChange?(x: string): void
|
||||
}
|
||||
|
||||
export function RadioGroup({
|
||||
children,
|
||||
value: propsValue,
|
||||
onChange,
|
||||
}: RadioGroupProps) {
|
||||
const [value, setValue] = useState(propsValue ? propsValue : '')
|
||||
|
||||
const handleChange = (e: string) => {
|
||||
if (onChange) onChange(e)
|
||||
setValue(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<RadixContextMenu.RadioGroup value={value} onValueChange={handleChange}>
|
||||
{children}
|
||||
</RadixContextMenu.RadioGroup>
|
||||
)
|
||||
}
|
||||
|
||||
interface LabelProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export function Label({ children }: LabelProps) {
|
||||
return (
|
||||
<RadixContextMenu.Label
|
||||
// className={ContextMenuStyles['sbui-contextmenu-label']}
|
||||
>
|
||||
{children}
|
||||
</RadixContextMenu.Label>
|
||||
)
|
||||
}
|
||||
|
||||
ContextMenu.Item = Item
|
||||
ContextMenu.Misc = Misc
|
||||
ContextMenu.Checkbox = Checkbox
|
||||
ContextMenu.Radio = Radio
|
||||
ContextMenu.RadioGroup = RadioGroup
|
||||
ContextMenu.Label = Label
|
||||
export default ContextMenu
|
||||
@@ -0,0 +1 @@
|
||||
export { default as ContextMenu } from './ContextMenu'
|
||||
@@ -0,0 +1,101 @@
|
||||
.sbui-divider {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sbui-divider-vertical {
|
||||
@apply bg-gray-200 dark:bg-dark-500;
|
||||
width: 1px;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.sbui-divider-vertical.sbui-divider--light {
|
||||
@apply bg-gray-100 dark:bg-dark-600;
|
||||
}
|
||||
|
||||
.sbui-divider--no-text {
|
||||
@apply border-gray-200 dark:border-dark-500;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.sbui-divider > span {
|
||||
@apply text-sm;
|
||||
@apply text-gray-300;
|
||||
@apply dark:text-dark-400;
|
||||
display: inline-block;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
.sbui-divider--left:before {
|
||||
@apply border-gray-200 dark:border-dark-500;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
top: 50%;
|
||||
content: '';
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 5%;
|
||||
}
|
||||
|
||||
.sbui-divider--left:after {
|
||||
@apply border-gray-200 dark:border-dark-500;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
top: 50%;
|
||||
content: '';
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.sbui-divider--right:before {
|
||||
@apply border-gray-200 dark:border-dark-500;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
top: 50%;
|
||||
content: '';
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.sbui-divider--right:after {
|
||||
@apply border-gray-200 dark:border-dark-500;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
top: 50%;
|
||||
content: '';
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 5%;
|
||||
}
|
||||
|
||||
.sbui-divider--center:before,
|
||||
.sbui-divider--center:after {
|
||||
@apply border-gray-200 dark:border-dark-500;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
top: 50%;
|
||||
content: '';
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.sbui-divider--light.sbui-divider--left:before,
|
||||
.sbui-divider--light.sbui-divider--left:after,
|
||||
.sbui-divider--light.sbui-divider--right:before,
|
||||
.sbui-divider--light.sbui-divider--right:after,
|
||||
.sbui-divider--light.sbui-divider--center:before,
|
||||
.sbui-divider--light.sbui-divider--center:after,
|
||||
.sbui-divider--light.sbui-divider--no-text {
|
||||
@apply border-gray-100 dark:border-dark-600;
|
||||
}
|
||||
|
||||
.sbui-divider--light.sbui-divider > span {
|
||||
@apply text-gray-200;
|
||||
@apply dark:text-dark-800;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import React from 'react'
|
||||
import { Button } from '../Button'
|
||||
import Typography from '../Typography'
|
||||
import { Divider } from './'
|
||||
|
||||
export default {
|
||||
title: 'Utilities/Divider',
|
||||
component: Divider,
|
||||
}
|
||||
|
||||
export const Default = (args: any) => <Divider {...args} />
|
||||
|
||||
export const withCenterText = (args: any) => (
|
||||
<Divider {...args}>Hello world</Divider>
|
||||
)
|
||||
|
||||
export const withLeftText = (args: any) => (
|
||||
<Divider {...args}>Hello world</Divider>
|
||||
)
|
||||
|
||||
export const withRightText = (args: any) => (
|
||||
<Divider {...args}>Hello world</Divider>
|
||||
)
|
||||
|
||||
export const lighterColor = (args: any) => <Divider {...args} />
|
||||
|
||||
export const vertical = (args: any) => (
|
||||
<div style={{ height: '32px' }}>
|
||||
<div className="space-x-3 w-full">
|
||||
<Divider {...args} />
|
||||
<Button>Button one</Button>
|
||||
<Divider {...args} />
|
||||
<Button>Button two</Button>
|
||||
<Divider {...args} />
|
||||
<Typography.Text>Some text</Typography.Text>
|
||||
<Divider {...args} />
|
||||
<Button>Button three</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Default.args = {}
|
||||
|
||||
withCenterText.args = {}
|
||||
|
||||
withLeftText.args = {
|
||||
orientation: 'left',
|
||||
}
|
||||
|
||||
withRightText.args = {
|
||||
orientation: 'right',
|
||||
}
|
||||
|
||||
lighterColor.args = {
|
||||
light: true,
|
||||
}
|
||||
|
||||
vertical.args = {
|
||||
type: 'vertical',
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import React from 'react'
|
||||
// @ts-ignore
|
||||
// import DividerStyles from './Divider.module.css'
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode
|
||||
className?: string
|
||||
light?: boolean
|
||||
orientation?: 'left' | 'right' | 'center'
|
||||
style?: React.CSSProperties
|
||||
type?: 'vertical' | 'horizontal'
|
||||
}
|
||||
|
||||
export default function Divider({
|
||||
children,
|
||||
className,
|
||||
light = false,
|
||||
orientation = 'center',
|
||||
style,
|
||||
type = 'horizontal',
|
||||
}: Props) {
|
||||
// let classes = [
|
||||
// type === 'horizontal'
|
||||
// ? DividerStyles['sbui-divider']
|
||||
// : DividerStyles['sbui-divider-vertical'],
|
||||
// ]
|
||||
// if (light) classes.push(DividerStyles['sbui-divider--light'])
|
||||
|
||||
// if (children) {
|
||||
// classes.push(DividerStyles[`sbui-divider--${orientation}`])
|
||||
// } else if (!children && type === 'horizontal') {
|
||||
// classes.push(DividerStyles[`sbui-divider--no-text`])
|
||||
// }
|
||||
|
||||
// if (className) classes.push(className)
|
||||
|
||||
return (
|
||||
<div
|
||||
// className={classes.join(' ')}
|
||||
role="seperator"
|
||||
style={style}
|
||||
>
|
||||
{children && (
|
||||
<span
|
||||
// className={DividerStyles['sbui-divider__content']}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Divider } from './Divider'
|
||||
@@ -0,0 +1,112 @@
|
||||
/* .sbui-dropdown-item {
|
||||
@apply text-xs;
|
||||
@apply text-typography-body-light dark:text-typography-body-dark;
|
||||
@apply px-4 py-1.5 flex items-center space-x-2;
|
||||
@apply cursor-pointer;
|
||||
@apply focus:bg-bg-secondary-light dark:focus:bg-bg-primary-dark border-none;
|
||||
cursor: 'default';
|
||||
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* .sbui-dropdown-item svg {
|
||||
@apply text-typography-body-secondary-light dark:text-typography-body-secondary-dark;
|
||||
} */
|
||||
|
||||
/* .sbui-dropdown-label {
|
||||
@apply text-typography-body-secondary-light dark:text-typography-body-secondary-dark;
|
||||
@apply px-4 py-1.5 flex items-center space-x-2;
|
||||
font-size: 0.65rem;
|
||||
}
|
||||
|
||||
.sbui-dropdown-misc {
|
||||
@apply px-4 py-1.5;
|
||||
}
|
||||
|
||||
.sbui-dropdown-item:focus-visible {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.sbui-dropdown-input {
|
||||
@apply flex items-center space-x-0 pl-8 pr-4;
|
||||
}
|
||||
|
||||
.sbui-dropdown-input__check {
|
||||
@apply absolute left-2;
|
||||
@apply flex items-center;
|
||||
} */
|
||||
|
||||
/* .sbui-dropdown__content {
|
||||
@apply bg-bg-primary-light dark:bg-bg-secondary-dark p-0;
|
||||
@apply border border-lightmode dark:border-darkmode;
|
||||
@apply rounded;
|
||||
@apply shadow;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
} */
|
||||
|
||||
/* @keyframes fadeIn {
|
||||
from {
|
||||
transform: scale(0.95);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
from {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: scale(0.95);
|
||||
opacity: 0;
|
||||
}
|
||||
} */
|
||||
/* .sbui-dropdown__content {
|
||||
transform-origin: 'var(--radix-dropdown-menu-content-transform-origin)';
|
||||
} */
|
||||
|
||||
/* .sbui-dropdown__content[data-state='open'] {
|
||||
animation: fadeIn 50ms ease-out;
|
||||
}
|
||||
|
||||
.sbui-dropdown__content[data-state='closed'] {
|
||||
animation: fadeOut 50ms ease-in;
|
||||
} */
|
||||
|
||||
/* .sbui-dropdown__trigger {
|
||||
@apply border-none bg-transparent p-0 focus:ring-0;
|
||||
} */
|
||||
|
||||
/* .sbui-dropdown__arrow {
|
||||
@apply fill-current text-bg-primary-light dark:text-bg-secondary-dark;
|
||||
@apply border-0 border-t;
|
||||
border-style: solid;
|
||||
|
||||
}
|
||||
|
||||
.sbui-dropdown-item-trigger {
|
||||
@apply text-xs;
|
||||
@apply text-typography-body-light dark:text-typography-body-dark;
|
||||
@apply px-4 py-1.5 flex items-center space-x-2;
|
||||
@apply cursor-pointer;
|
||||
cursor: 'default';
|
||||
}
|
||||
|
||||
.sbui-dropdown-item-trigger svg {
|
||||
@apply text-typography-body-secondary-light dark:text-typography-body-secondary-dark;
|
||||
}
|
||||
|
||||
.sbui-dropdown-item-trigger:focus-visible {
|
||||
border: none;
|
||||
outline: none;
|
||||
} */
|
||||
|
||||
/* .sbui-dropdown__trigger-item[data-state='open'] {
|
||||
@apply bg-bg-secondary-light dark:bg-bg-primary-dark border-none;
|
||||
} */
|
||||
@@ -0,0 +1,347 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Button } from '../Button'
|
||||
import { Divider } from '../Divider'
|
||||
import {
|
||||
IconSettings,
|
||||
IconLogOut,
|
||||
IconChevronDown,
|
||||
IconChevronRight,
|
||||
IconHardDrive,
|
||||
} from './../../index'
|
||||
import Typography from '../Typography'
|
||||
|
||||
import { Dropdown } from './'
|
||||
import { IconLogIn } from '../Icon/icons/IconLogIn'
|
||||
import { Input } from '../Input'
|
||||
import { IconSearch } from '../Icon/icons/IconSearch'
|
||||
|
||||
export default {
|
||||
title: 'Navigation/Dropdown',
|
||||
component: Dropdown,
|
||||
}
|
||||
|
||||
const DemoContainer = ({ children }: { children: React.ReactNode }) => (
|
||||
<div
|
||||
className="
|
||||
flex justify-center items-center
|
||||
w-screen h-screen
|
||||
"
|
||||
>
|
||||
<div
|
||||
className="
|
||||
p-3 px-5
|
||||
bg-scale-300 border border-scale-600 rounded flex gap-4
|
||||
justify-between
|
||||
items-center
|
||||
w-3/4
|
||||
"
|
||||
>
|
||||
<div>
|
||||
<h4 className="text-scale-1200 text-base">
|
||||
Shall we nest some components?
|
||||
</h4>
|
||||
<p className="text-scale-1100 text-sm">yea sure, go on then.</p>
|
||||
</div>
|
||||
<div className="relative">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
export const DefaultFull = (args: any) => {
|
||||
const [checked, setChecked] = useState(false)
|
||||
const [value, setValue] = useState('red')
|
||||
|
||||
return (
|
||||
<DemoContainer>
|
||||
<Dropdown
|
||||
side="bottom"
|
||||
align="end"
|
||||
overlay={[
|
||||
<Dropdown.Misc>
|
||||
<div>
|
||||
<Typography.Text small className="block">
|
||||
Signed in as{' '}
|
||||
</Typography.Text>
|
||||
|
||||
<Typography.Text small strong>
|
||||
tom@example.com{' '}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Dropdown.Misc>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Label>Group label</Dropdown.Label>,
|
||||
<Dropdown.Item onClick={() => console.log('clicked')}>
|
||||
Account
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Item>
|
||||
Settings <Dropdown.RightSlot>⌘+T</Dropdown.RightSlot>
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Checkbox checked={checked} onChange={setChecked}>
|
||||
Show subtitles
|
||||
</Dropdown.Checkbox>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.RadioGroup value={value} onChange={setValue}>
|
||||
<Dropdown.Radio value={'red'}>Red</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'blue'}>Blue</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'green'}>Green</Dropdown.Radio>
|
||||
</Dropdown.RadioGroup>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown
|
||||
isNested
|
||||
overlay={[
|
||||
<Dropdown.RadioGroup value={value} onChange={setValue}>
|
||||
<Dropdown.Radio value={'red'}>Red</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'blue'}>Blue</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'green'}>Green</Dropdown.Radio>
|
||||
</Dropdown.RadioGroup>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Label>Group label</Dropdown.Label>,
|
||||
<Dropdown.Item onClick={() => console.log('clicked')}>
|
||||
Account
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Item>
|
||||
Settings <Dropdown.RightSlot>⌘+T</Dropdown.RightSlot>
|
||||
</Dropdown.Item>,
|
||||
]}
|
||||
>
|
||||
<Dropdown.TriggerItem icon={<IconHardDrive />}>
|
||||
Open sub menu{' '}
|
||||
<Dropdown.RightSlot>
|
||||
<IconChevronRight size={14} />
|
||||
</Dropdown.RightSlot>
|
||||
</Dropdown.TriggerItem>
|
||||
</Dropdown>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Item icon={<IconLogIn size="tiny" />}>
|
||||
Log out
|
||||
</Dropdown.Item>,
|
||||
]}
|
||||
>
|
||||
<Button as="span" type="default" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</DemoContainer>
|
||||
)
|
||||
}
|
||||
|
||||
export const Default = (args: any) => (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<Dropdown
|
||||
{...args}
|
||||
overlay={[
|
||||
<Dropdown.Misc>
|
||||
<div>
|
||||
<Typography.Text small className="block">
|
||||
Signed in as{' '}
|
||||
</Typography.Text>
|
||||
|
||||
<Typography.Text small strong>
|
||||
tom@example.com{' '}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</Dropdown.Misc>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Label>Group label</Dropdown.Label>,
|
||||
<Dropdown.Item onClick={() => console.log('clicked')}>
|
||||
Account
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Item>
|
||||
Settings <Dropdown.RightSlot>⌘+T</Dropdown.RightSlot>
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Item icon={<IconLogIn size="tiny" />}>Log out</Dropdown.Item>,
|
||||
]}
|
||||
>
|
||||
<Button as="span" type="secondary" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
|
||||
Default.args = {}
|
||||
|
||||
export const doNotcloseOverlay = (args: any) => (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<Dropdown
|
||||
{...args}
|
||||
overlay={[
|
||||
<Dropdown.Misc>
|
||||
<Typography.Text>Signed in as </Typography.Text>
|
||||
<Typography.Text strong>tom@example.com </Typography.Text>
|
||||
</Dropdown.Misc>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Item>Account</Dropdown.Item>,
|
||||
<Dropdown.Item>Settings</Dropdown.Item>,
|
||||
<Dropdown.Item>
|
||||
<Button icon={<IconLogOut />}>Log out</Button>
|
||||
</Dropdown.Item>,
|
||||
]}
|
||||
>
|
||||
<Button as="span" type="outline" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
|
||||
doNotcloseOverlay.args = {}
|
||||
|
||||
export const withCustomStyles = (args: any) => (
|
||||
<div
|
||||
style={{
|
||||
margin: '0 auto',
|
||||
minHeight: '420px',
|
||||
marginTop: '220px',
|
||||
marginLeft: '400px',
|
||||
}}
|
||||
>
|
||||
<Dropdown
|
||||
overlayStyle={{ minWidth: '500px' }}
|
||||
placement="bottomRight"
|
||||
{...args}
|
||||
overlay={[
|
||||
<Dropdown.Item>
|
||||
<Typography.Text>Signed in as </Typography.Text>
|
||||
<Typography.Text strong>tom@example.com </Typography.Text>
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Item>Account</Dropdown.Item>,
|
||||
<Dropdown.Item>Settings</Dropdown.Item>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Item>
|
||||
<Button type="default" icon={<IconLogOut />}>
|
||||
Log out
|
||||
</Button>
|
||||
</Dropdown.Item>,
|
||||
]}
|
||||
>
|
||||
<Button as="span" type="outline" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
|
||||
withCustomStyles.args = {}
|
||||
|
||||
export const SearchList = (args: any) => (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<Dropdown
|
||||
{...args}
|
||||
overlay={[
|
||||
<Dropdown.Item>
|
||||
<Input size="tiny" icon={<IconSearch />} autofocus={false} />
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Item>
|
||||
<Typography.Text>Signed in as </Typography.Text>
|
||||
<Typography.Text strong>tom@example.com </Typography.Text>
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Item>
|
||||
<Typography.Text>Signed in as </Typography.Text>
|
||||
<Typography.Text strong>tom@example.com </Typography.Text>
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Item icon={<IconLogIn />}>
|
||||
<Typography.Text>Log out</Typography.Text>
|
||||
</Dropdown.Item>,
|
||||
]}
|
||||
>
|
||||
<Button as="span" type="outline" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
|
||||
SearchList.args = {}
|
||||
|
||||
export const Checkbox = (args: any) => {
|
||||
const [checked, setChecked] = useState(false)
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<Dropdown
|
||||
{...args}
|
||||
overlay={[
|
||||
<Dropdown.Item icon={<IconSettings size="small" />}>
|
||||
Account
|
||||
</Dropdown.Item>,
|
||||
<Dropdown.Item>Settings</Dropdown.Item>,
|
||||
<Dropdown.Seperator />,
|
||||
<Dropdown.Checkbox checked={checked} onChange={setChecked}>
|
||||
Show subtitles
|
||||
</Dropdown.Checkbox>,
|
||||
]}
|
||||
>
|
||||
<Button as="span" type="outline" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const Radio = (args: any) => {
|
||||
const [value, setValue] = useState('red')
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<Dropdown
|
||||
{...args}
|
||||
overlay={[
|
||||
<Dropdown.RadioGroup value={value} onChange={setValue}>
|
||||
<Dropdown.Radio value={'red'}>Red</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'blue'}>Blue</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'green'}>Green</Dropdown.Radio>
|
||||
</Dropdown.RadioGroup>,
|
||||
]}
|
||||
>
|
||||
<Button as="span" type="outline" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const Nested = (args: any) => {
|
||||
const [value, setValue] = useState('red')
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 auto', minHeight: '420px', marginTop: '220px' }}>
|
||||
<Dropdown
|
||||
{...args}
|
||||
overlay={
|
||||
<>
|
||||
<Dropdown.RadioGroup value={value} onChange={setValue}>
|
||||
<Dropdown.Radio value={'red'}>Red</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'blue'}>Blue</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'green'}>Green</Dropdown.Radio>
|
||||
</Dropdown.RadioGroup>
|
||||
|
||||
<Dropdown
|
||||
isNested
|
||||
overlay={[
|
||||
<Dropdown.RadioGroup value={value} onChange={setValue}>
|
||||
<Dropdown.Radio value={'red'}>Red</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'blue'}>Blue</Dropdown.Radio>
|
||||
<Dropdown.Radio value={'green'}>Green</Dropdown.Radio>
|
||||
</Dropdown.RadioGroup>,
|
||||
]}
|
||||
>
|
||||
<Dropdown.TriggerItem>Open sub menu</Dropdown.TriggerItem>
|
||||
</Dropdown>
|
||||
<Dropdown.Item>hello</Dropdown.Item>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Button as="span" type="outline" iconRight={<IconChevronDown />}>
|
||||
Click for dropdown
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import * as RadixDropdown from '@radix-ui/react-dropdown-menu'
|
||||
import { IconCheck } from '../Icon/icons/IconCheck'
|
||||
|
||||
// @ts-ignore
|
||||
// import DropdownStyles from './Dropdown.module.css'
|
||||
|
||||
import type * as RadixDropdownTypes from '@radix-ui/react-dropdown-menu/'
|
||||
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
import { IconTarget } from '../Icon/icons/IconTarget'
|
||||
|
||||
interface RootProps {
|
||||
open?: boolean
|
||||
arrow?: boolean
|
||||
onOpenChange?: RadixDropdownTypes.DropdownMenuProps['onOpenChange'] // DropdownMenu['onOpenChange']
|
||||
side?: RadixDropdownTypes.DropdownMenuContentProps['side']
|
||||
align?: RadixDropdownTypes.DropdownMenuContentProps['align']
|
||||
sideOffset?: RadixDropdownTypes.DropdownMenuContentProps['sideOffset']
|
||||
overlay?: React.ReactNode
|
||||
children?: React.ReactNode
|
||||
size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge' | 'content'
|
||||
className?: string
|
||||
style?: React.CSSProperties
|
||||
isNested?: Boolean
|
||||
}
|
||||
|
||||
function Dropdown({
|
||||
open,
|
||||
onOpenChange,
|
||||
align = 'center', //Default value
|
||||
side = 'bottom', //Default value
|
||||
sideOffset = 6,
|
||||
overlay,
|
||||
children,
|
||||
size = 'medium',
|
||||
className,
|
||||
style,
|
||||
arrow,
|
||||
isNested,
|
||||
}: RootProps) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
|
||||
let classes = [__styles.content, __styles.size[size]]
|
||||
if (className) {
|
||||
classes.push(className)
|
||||
}
|
||||
|
||||
return (
|
||||
<RadixDropdown.Root onOpenChange={onOpenChange} open={open}>
|
||||
{isNested ? (
|
||||
<RadixDropdown.TriggerItem className={[__styles.item_nested].join(' ')}>
|
||||
{children}
|
||||
</RadixDropdown.TriggerItem>
|
||||
) : (
|
||||
<RadixDropdown.Trigger className={__styles.trigger}>{children}</RadixDropdown.Trigger>
|
||||
)}
|
||||
|
||||
<RadixDropdown.Content
|
||||
portalled={true}
|
||||
sideOffset={sideOffset}
|
||||
side={side}
|
||||
align={align}
|
||||
className={classes.join(' ')}
|
||||
style={style}
|
||||
>
|
||||
{arrow && (
|
||||
<RadixDropdown.Arrow className={__styles.arrow} offset={10}></RadixDropdown.Arrow>
|
||||
)}
|
||||
{overlay}
|
||||
</RadixDropdown.Content>
|
||||
</RadixDropdown.Root>
|
||||
)
|
||||
}
|
||||
|
||||
export function RightSlot({ children }: any) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
return <div className={__styles.right_slot}>{children}</div>
|
||||
}
|
||||
|
||||
interface ItemProps {
|
||||
children: React.ReactNode
|
||||
icon?: React.ReactNode
|
||||
disabled?: boolean
|
||||
onClick?: (event: Event) => void
|
||||
rightSlot?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Item({ children, icon, disabled, onClick, rightSlot }: ItemProps) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
|
||||
return (
|
||||
<RadixDropdown.Item className={__styles.item} disabled={disabled} onSelect={onClick}>
|
||||
{icon && icon}
|
||||
<span>{children}</span>
|
||||
</RadixDropdown.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export function TriggerItem({ children, icon, disabled }: ItemProps) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
return (
|
||||
<div className={__styles.item}>
|
||||
{icon && icon}
|
||||
<span>{children}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function Misc({ children, icon }: ItemProps) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
return (
|
||||
<div className={__styles.misc}>
|
||||
{icon && icon}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface CheckboxProps {
|
||||
children: React.ReactNode
|
||||
checked?: boolean
|
||||
onChange?(x: boolean): void
|
||||
disabled?: boolean
|
||||
ItemIndicator?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Seperator() {
|
||||
let __styles = styleHandler('dropdown')
|
||||
|
||||
return <RadixDropdown.Separator className={__styles.seperator} />
|
||||
}
|
||||
|
||||
export function Checkbox({
|
||||
children,
|
||||
checked: propsChecked,
|
||||
onChange,
|
||||
disabled,
|
||||
ItemIndicator,
|
||||
}: CheckboxProps) {
|
||||
const [checked, setChecked] = useState(propsChecked ? propsChecked : false)
|
||||
|
||||
let __styles = styleHandler('dropdown')
|
||||
|
||||
const handleChange = (e: boolean) => {
|
||||
if (onChange) onChange(e)
|
||||
setChecked(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<RadixDropdown.CheckboxItem
|
||||
checked={checked}
|
||||
onCheckedChange={handleChange}
|
||||
className={`${__styles.item} ${__styles.input}`}
|
||||
disabled={disabled}
|
||||
>
|
||||
<RadixDropdown.ItemIndicator className={__styles.check}>
|
||||
{ItemIndicator ? ItemIndicator : <IconCheck size="tiny" strokeWidth={3} />}
|
||||
<RadixDropdown.CheckboxItem />
|
||||
</RadixDropdown.ItemIndicator>
|
||||
<span>{children}</span>
|
||||
</RadixDropdown.CheckboxItem>
|
||||
)
|
||||
}
|
||||
|
||||
interface RadioProps {
|
||||
children: React.ReactNode
|
||||
value: string
|
||||
ItemIndicator?: React.ReactNode
|
||||
}
|
||||
|
||||
export function Radio({ children, value, ItemIndicator }: RadioProps) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
|
||||
return (
|
||||
<RadixDropdown.RadioItem value={value} className={`${__styles.item} ${__styles.input}`}>
|
||||
<RadixDropdown.ItemIndicator className={__styles.check}>
|
||||
{ItemIndicator ? ItemIndicator : <IconTarget strokeWidth={6} size={10} />}
|
||||
</RadixDropdown.ItemIndicator>
|
||||
<span>{children}</span>
|
||||
</RadixDropdown.RadioItem>
|
||||
)
|
||||
}
|
||||
|
||||
interface RadioGroupProps {
|
||||
children: React.ReactNode
|
||||
value: string
|
||||
onChange?(x: string): void
|
||||
}
|
||||
|
||||
export function RadioGroup({ children, value: propsValue, onChange }: RadioGroupProps) {
|
||||
const [value, setValue] = useState(propsValue ? propsValue : '')
|
||||
|
||||
const handleChange = (e: string) => {
|
||||
if (onChange) onChange(e)
|
||||
setValue(e)
|
||||
}
|
||||
|
||||
return (
|
||||
<RadixDropdown.RadioGroup value={value} onValueChange={handleChange}>
|
||||
{children}
|
||||
</RadixDropdown.RadioGroup>
|
||||
)
|
||||
}
|
||||
|
||||
interface LabelProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export function Label({ children }: LabelProps) {
|
||||
let __styles = styleHandler('dropdown')
|
||||
|
||||
return <RadixDropdown.Label className={__styles.label}>{children}</RadixDropdown.Label>
|
||||
}
|
||||
|
||||
Dropdown.Item = Item
|
||||
Dropdown.Misc = Misc
|
||||
Dropdown.Checkbox = Checkbox
|
||||
Dropdown.Radio = Radio
|
||||
Dropdown.RadioGroup = RadioGroup
|
||||
Dropdown.Label = Label
|
||||
Dropdown.Seperator = Seperator
|
||||
Dropdown.RightSlot = RightSlot
|
||||
Dropdown.TriggerItem = TriggerItem
|
||||
export default Dropdown
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Dropdown } from './Dropdown'
|
||||
Whitespace-only changes.
@@ -0,0 +1,569 @@
|
||||
import { Form } from '.'
|
||||
import {
|
||||
Input,
|
||||
Button,
|
||||
InputNumber,
|
||||
Toggle,
|
||||
Checkbox,
|
||||
Radio,
|
||||
Select,
|
||||
Listbox,
|
||||
} from '../../index'
|
||||
|
||||
import * as Yup from 'yup'
|
||||
import { User } from '../Icon/IconImportHandler'
|
||||
import React from 'react'
|
||||
|
||||
export default {
|
||||
title: 'Data Input/Form',
|
||||
component: Form,
|
||||
}
|
||||
|
||||
interface Values {
|
||||
email: string
|
||||
last_name: string
|
||||
profession: string
|
||||
number: number | undefined
|
||||
// remember_me: boolean
|
||||
checkbox_alone: boolean
|
||||
favorite_food: string
|
||||
check_3: boolean
|
||||
check_2: boolean
|
||||
check_1: boolean
|
||||
textarea: string
|
||||
toggle: boolean
|
||||
people: number | undefined
|
||||
}
|
||||
|
||||
const INITIAL_VALUES: Values = {
|
||||
email: '',
|
||||
last_name: '',
|
||||
profession: '',
|
||||
number: undefined,
|
||||
checkbox_alone: false,
|
||||
// remember_me: false,
|
||||
favorite_food: '',
|
||||
check_3: false,
|
||||
check_2: true,
|
||||
check_1: false,
|
||||
textarea: '',
|
||||
toggle: true,
|
||||
people: undefined,
|
||||
}
|
||||
|
||||
export const InputLevelValidation = () => {
|
||||
function validateEmail(value: string) {
|
||||
console.log('validateEmail running')
|
||||
let error
|
||||
if (!value) {
|
||||
error = 'Required'
|
||||
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) {
|
||||
error = 'Invalid email address'
|
||||
}
|
||||
return error
|
||||
}
|
||||
|
||||
return (
|
||||
<Form
|
||||
initialValues={{
|
||||
email: '',
|
||||
firstname: '',
|
||||
}}
|
||||
validateOnBlur
|
||||
onSubmit={(values: any, { setSubmitting }: any) => {
|
||||
setTimeout(() => {
|
||||
alert(JSON.stringify(values, null, 2))
|
||||
setSubmitting(false)
|
||||
}, 400)
|
||||
}}
|
||||
>
|
||||
{({ isSubmitting }: { isSubmitting: boolean }) => (
|
||||
<div className="space-y-4">
|
||||
<Input
|
||||
id="email"
|
||||
label="email"
|
||||
placeholder="something in here"
|
||||
labelOptional="This is a required field"
|
||||
validation={validateEmail}
|
||||
/>
|
||||
{/* <Input
|
||||
id="firstname"
|
||||
label="firstname"
|
||||
placeholder="something in here"
|
||||
/> */}
|
||||
<Button loading={isSubmitting} type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export const InputLevelValidationYip = () => {
|
||||
// validation schema
|
||||
const SignupSchema = Yup.object().shape({
|
||||
firstname: Yup.string()
|
||||
.min(2, 'Too Short!')
|
||||
.max(50, 'Too Long!')
|
||||
.required('Required'),
|
||||
lastname: Yup.string()
|
||||
.min(2, 'Too Short!')
|
||||
.max(50, 'Too Long!')
|
||||
.required('Required'),
|
||||
email: Yup.string().email('Invalid email').required('Required'),
|
||||
})
|
||||
|
||||
return (
|
||||
<Form
|
||||
initialValues={{
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
email: '',
|
||||
}}
|
||||
validationSchema={SignupSchema}
|
||||
onSubmit={(values: any, { setSubmitting }: any) => {
|
||||
setTimeout(() => {
|
||||
alert(JSON.stringify(values, null, 2))
|
||||
setSubmitting(false)
|
||||
}, 400)
|
||||
}}
|
||||
>
|
||||
{({ isSubmitting }: any) => (
|
||||
<div className="space-y-4">
|
||||
<Input
|
||||
id="firstname"
|
||||
name="firstname"
|
||||
label="firstname"
|
||||
placeholder="firstname"
|
||||
/>
|
||||
<Input
|
||||
id="lastname"
|
||||
name="lastname"
|
||||
label="lastname"
|
||||
placeholder="lastname"
|
||||
/>
|
||||
<Input
|
||||
id="email"
|
||||
name="email"
|
||||
label="Email"
|
||||
placeholder="This is your email"
|
||||
/>
|
||||
<Button loading={isSubmitting} type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
const people = [
|
||||
{
|
||||
value: 1,
|
||||
label: 'Wade Cooper',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: 'Arlene Mccoy',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: 'Devon Webb',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: 'Tom Cook',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 5,
|
||||
label: 'Tanya Fox',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 6,
|
||||
label: 'Hellen Schmidt',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 7,
|
||||
label: 'Caroline Schultz',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1568409938619-12e139227838?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 8,
|
||||
label: 'Mason Heaney',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 9,
|
||||
label: 'Claudie Smitham',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1584486520270-19eca1efcce5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
{
|
||||
value: 10,
|
||||
label: 'Emil Schaefer',
|
||||
avatar:
|
||||
'https://images.unsplash.com/photo-1561505457-3bcad021f8ee?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
|
||||
},
|
||||
]
|
||||
|
||||
export const LargerExample = () => {
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
initialValues={INITIAL_VALUES}
|
||||
onSubmit={(values: any, { setSubmitting }: any) => {
|
||||
setTimeout(() => {
|
||||
alert(JSON.stringify(values, null, 2))
|
||||
setSubmitting(false)
|
||||
}, 400)
|
||||
}}
|
||||
validate={(values: Values) => {
|
||||
const errors: any = {}
|
||||
|
||||
console.log('values for validation', values)
|
||||
|
||||
if (!values.email) {
|
||||
errors.email = 'Required'
|
||||
} else if (
|
||||
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
|
||||
) {
|
||||
errors.email = 'Invalid email address'
|
||||
}
|
||||
|
||||
if (!values.profession) {
|
||||
errors.profession = 'Required'
|
||||
}
|
||||
|
||||
if (!values.textarea) {
|
||||
errors.textarea = 'Required'
|
||||
}
|
||||
|
||||
if (!values.number) {
|
||||
errors.number = 'Required'
|
||||
}
|
||||
|
||||
if (values.number <= 13) {
|
||||
errors.number = 'Must be a number above 13'
|
||||
}
|
||||
|
||||
if (values.number >= 32) {
|
||||
errors.number = 'Must be a number below 32'
|
||||
}
|
||||
|
||||
if (!values.favorite_food) {
|
||||
errors.favorite_food = 'You must select a favourite food'
|
||||
}
|
||||
|
||||
if (!values.toggle) {
|
||||
errors.toggle = 'This needs to be turned on'
|
||||
}
|
||||
|
||||
// if (!values.people) {
|
||||
// errors.people = 'Please select a person'
|
||||
// }
|
||||
|
||||
// if (values.remember_me)
|
||||
|
||||
return errors
|
||||
}}
|
||||
>
|
||||
{({ isSubmitting }: any) => (
|
||||
<>
|
||||
<div className="space-y-8">
|
||||
<p>{isSubmitting ? 'submitting' : 'not submitting'}</p>
|
||||
<Input
|
||||
id="email"
|
||||
label="Email"
|
||||
placeholder="something@gmail.com"
|
||||
/>
|
||||
<Input
|
||||
id="last_name"
|
||||
label="last name"
|
||||
placeholder="something in here"
|
||||
/>
|
||||
<Select
|
||||
id="profession"
|
||||
label="Profession"
|
||||
placeholder="something in here"
|
||||
>
|
||||
<Select.Option key="empty-enum" value="">
|
||||
---
|
||||
</Select.Option>
|
||||
<Select.Option value="teacher">Teacher</Select.Option>
|
||||
<Select.Option value="firefighter">Firefighter</Select.Option>
|
||||
<Select.Option value="police">Police</Select.Option>
|
||||
</Select>
|
||||
<InputNumber
|
||||
id="number"
|
||||
label="Number"
|
||||
placeholder="124"
|
||||
labelOptional="Must be between 13 - 31"
|
||||
/>
|
||||
<Checkbox id="checkbox_alone" label="checkbox_alone" />
|
||||
<Input.TextArea id="textarea" rows={5} name="textarea" />
|
||||
<Checkbox.Group
|
||||
label="Group of checkboxes"
|
||||
layout="horizontal"
|
||||
labelOptional="Optional label"
|
||||
descriptionText="You can also show label hint text here"
|
||||
>
|
||||
<Checkbox
|
||||
name="check_1"
|
||||
id="check_1"
|
||||
label="Remember me"
|
||||
description="hello world"
|
||||
/>
|
||||
<Checkbox
|
||||
name="check_2"
|
||||
id="check_2"
|
||||
label="Remember me"
|
||||
description="hello world"
|
||||
/>
|
||||
<Checkbox
|
||||
name="check_3"
|
||||
id="check_3"
|
||||
label="Remember me"
|
||||
description="hello world"
|
||||
/>
|
||||
</Checkbox.Group>
|
||||
<Toggle id="toggle" label="Remember me" layout="horizontal" />
|
||||
<Radio.Group
|
||||
layout="horizontal"
|
||||
name="favorite_food"
|
||||
label="favorite_food"
|
||||
type="list"
|
||||
>
|
||||
<Radio value="pizza" label="Pizza" description="hello world" />
|
||||
<Radio
|
||||
value="burger"
|
||||
label="Burger"
|
||||
description="hello world"
|
||||
/>
|
||||
<Radio value="fries" label="Fries" description="hello world" />
|
||||
</Radio.Group>
|
||||
|
||||
<Listbox
|
||||
id="people"
|
||||
label="Choose a person"
|
||||
layout="horizontal"
|
||||
descriptionText="Choose a person for this role"
|
||||
>
|
||||
{people.map((person) => {
|
||||
return (
|
||||
<Listbox.Option
|
||||
key={`people-${person.value}`}
|
||||
value={person.value}
|
||||
label={person.label}
|
||||
addOnBefore={({ active, selected }: any) => (
|
||||
<img
|
||||
src={person.avatar}
|
||||
alt=""
|
||||
className="h-6 w-6 rounded-full"
|
||||
/>
|
||||
)}
|
||||
children={({ active, selected }: any) => {
|
||||
// console.log('selected', selected)
|
||||
// console.log('active', active)
|
||||
return (
|
||||
<span className={'font-normal block truncate'}>
|
||||
{person.label}
|
||||
</span>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</Listbox>
|
||||
|
||||
<Button loading={isSubmitting} type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const CardForm = () => {
|
||||
// panel
|
||||
const Panel = ({
|
||||
children,
|
||||
header,
|
||||
footer,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
header?: React.ReactNode
|
||||
footer?: React.ReactNode
|
||||
}) => (
|
||||
<div className="bg-scale-300 border border-scale-400 rounded-md w-3/4 mx-auto my-8 shadow overflow-hidden">
|
||||
{header && (
|
||||
<div className="bg-scale-100 dark:bg-scale-200 px-8 py-4 border-b border-scale-400">
|
||||
{header}
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-6 py-6">{children}</div>
|
||||
{footer}
|
||||
</div>
|
||||
)
|
||||
|
||||
const Section = ({
|
||||
children,
|
||||
header,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
header?: React.ReactNode
|
||||
}) => (
|
||||
<div className="grid grid-cols-12 px-8 py-2">
|
||||
{header}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
initialValues={{ stripe_email_choice: 'emails-2' }}
|
||||
onSubmit={(values: any, { setSubmitting }: any) => {
|
||||
setTimeout(() => {
|
||||
alert(JSON.stringify(values, null, 2))
|
||||
setSubmitting(false)
|
||||
}, 400)
|
||||
}}
|
||||
validate={(values: Values) => {
|
||||
const errors: any = {}
|
||||
|
||||
return errors
|
||||
}}
|
||||
>
|
||||
{({ isSubmitting }: any) => (
|
||||
<Panel
|
||||
header={
|
||||
<>
|
||||
<h3 className="text-scale-1200 text-xl font-semibold">
|
||||
Custom Options
|
||||
</h3>
|
||||
<p className="text-scale-900">
|
||||
These settings apply to payment pages you create using Stripe
|
||||
Checkout and Payment Links.
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
footer={
|
||||
<>
|
||||
<div className="border-t border-scale-400"></div>
|
||||
<div className="py-3 px-6 flex gap-2 justify-end">
|
||||
<Button
|
||||
loading={isSubmitting}
|
||||
type="secondary"
|
||||
htmlType="submit"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
loading={isSubmitting}
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{/* <p>{isSubmitting ? 'submitting' : 'not submitting'}</p> */}
|
||||
{/* <div className="border-t border-scale-400"></div> */}
|
||||
<Section
|
||||
header={
|
||||
<label className="text-sm text-scale-1200 col-span-4">
|
||||
Faster checkout
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<Toggle
|
||||
className="col-span-8"
|
||||
id="link_with_stripe"
|
||||
label="Turn on link with Stripe"
|
||||
layout="flex"
|
||||
descriptionText="Go to Payment methods settings to configure Apple Pay and Google Pay."
|
||||
/>
|
||||
</Section>
|
||||
<div className="border-t border-scale-400"></div>
|
||||
<Section
|
||||
header={
|
||||
<label className="text-sm text-scale-1200 col-span-4">
|
||||
Faster checkout
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<Radio.Group
|
||||
className="col-span-8"
|
||||
name="stripe_email_choice"
|
||||
id="stripe_email_choice"
|
||||
type="list"
|
||||
layout="vertical"
|
||||
>
|
||||
<Radio
|
||||
// id="1642469211631"
|
||||
value="emails-1"
|
||||
label="Send emails about upcoming renewals"
|
||||
description="hello world"
|
||||
align="horizontal"
|
||||
/>
|
||||
<Radio
|
||||
// id="1642469211606"
|
||||
value="emails-2"
|
||||
label="Send emails about expiring cards"
|
||||
description="hello world"
|
||||
align="horizontal"
|
||||
/>
|
||||
</Radio.Group>
|
||||
</Section>
|
||||
<div className="border-t border-scale-400"></div>
|
||||
<Section
|
||||
header={
|
||||
<label className="text-sm text-scale-1200 col-span-4">
|
||||
Faster checkout
|
||||
</label>
|
||||
}
|
||||
>
|
||||
<div className="col-span-8 space-y-4">
|
||||
<Input name="app_id" label="Application ID in Stripe" />
|
||||
<Input
|
||||
name="service_id"
|
||||
label="API key"
|
||||
descriptionText={
|
||||
<span>
|
||||
This can be found in{' '}
|
||||
<span className="text-brand-900 underline cursor-pointer transition hover:text-brand-800">
|
||||
the developer settings
|
||||
</span>
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Section>
|
||||
</Panel>
|
||||
)}
|
||||
</Form>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export { default as AuthForm } from './examples/AuthForm'
|
||||
@@ -0,0 +1,96 @@
|
||||
import { useReducer } from 'react'
|
||||
import { useFormik, FormikConfig } from 'formik'
|
||||
import { FormContextProvider } from './FormContext'
|
||||
|
||||
// interface Props extends FormikProps<any>, Partial FormikConfig<any> {
|
||||
interface Props
|
||||
extends Omit<FormikConfig<any>, 'validateOnMount' | 'validateOnChange'> {
|
||||
children: any
|
||||
handleIsSubmitting?: any
|
||||
handleIsValidating?: any
|
||||
name?: string
|
||||
id?: string
|
||||
className?: string
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
function errorReducer(state: any, action: any) {
|
||||
if (!action.error) {
|
||||
const payload = state
|
||||
delete payload[action.key]
|
||||
return payload
|
||||
}
|
||||
if (action) {
|
||||
return {
|
||||
...state,
|
||||
[action.key]: action.error,
|
||||
}
|
||||
} else {
|
||||
throw new Error()
|
||||
}
|
||||
}
|
||||
|
||||
export default function Form({ validate, ...props }: Props) {
|
||||
const [fieldLevelErrors, dispatchErrors] = useReducer(errorReducer, null)
|
||||
|
||||
function handleFieldLevelValidation(key: any, error: string) {
|
||||
dispatchErrors({ key, error })
|
||||
}
|
||||
|
||||
const formik = useFormik({
|
||||
validateOnBlur: true,
|
||||
...props,
|
||||
validationSchema: props.validationSchema,
|
||||
initialValues: props.initialValues,
|
||||
onSubmit: props.onSubmit,
|
||||
validate:
|
||||
validate ||
|
||||
function () {
|
||||
return fieldLevelErrors
|
||||
},
|
||||
})
|
||||
|
||||
// console.log('values', formik.values)
|
||||
// console.log('errors', formik.errors)
|
||||
// console.log('touched', formik.touched)
|
||||
|
||||
return (
|
||||
<form
|
||||
id={props.id}
|
||||
name={props.name}
|
||||
onSubmit={formik.handleSubmit}
|
||||
className={props.className}
|
||||
style={props.style}
|
||||
>
|
||||
<FormContextProvider
|
||||
values={formik.values}
|
||||
errors={formik.errors}
|
||||
formContextOnChange={formik.handleChange}
|
||||
handleBlur={formik.handleBlur}
|
||||
touched={formik.touched}
|
||||
fieldLevelValidation={handleFieldLevelValidation}
|
||||
// children={rest.children}
|
||||
children={props.children({
|
||||
/** map of field names to specific error for that field */
|
||||
errors: formik.errors, // errors,
|
||||
// /** map of field names to whether the field has been touched */
|
||||
touched: formik.touched,
|
||||
/** whether the form is currently submitting */
|
||||
isSubmitting: formik.isSubmitting,
|
||||
/** whether the form is currently validating (prior to submission) */
|
||||
isValidating: formik.isValidating,
|
||||
/** Number of times user tried to submit the form */
|
||||
submitCount: formik.submitCount,
|
||||
/** Initial values of form */
|
||||
initialValues: formik.initialValues,
|
||||
/** Current values of form */
|
||||
values: formik.values,
|
||||
/** Resets the form back to initialValues */
|
||||
handleReset: formik.handleReset,
|
||||
/** Resets the form with custom values */
|
||||
resetForm: formik.resetForm,
|
||||
})}
|
||||
/>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import React, { createContext, useContext } from 'react'
|
||||
|
||||
interface ContextProps {
|
||||
formContextOnChange: any
|
||||
values: any
|
||||
errors: any
|
||||
handleBlur: React.FocusEventHandler | null
|
||||
touched: any
|
||||
fieldLevelValidation: any
|
||||
}
|
||||
|
||||
interface Provider extends ContextProps {
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
// Make sure the shape of the default value passed to
|
||||
// createContext matches the shape that the consumers expect!
|
||||
const FormContext = createContext<ContextProps>({
|
||||
formContextOnChange: null,
|
||||
values: null,
|
||||
errors: null,
|
||||
handleBlur: null,
|
||||
touched: null,
|
||||
fieldLevelValidation: null,
|
||||
})
|
||||
|
||||
export const FormContextProvider = (props: Provider) => {
|
||||
const {
|
||||
formContextOnChange,
|
||||
values,
|
||||
errors,
|
||||
handleBlur,
|
||||
touched,
|
||||
fieldLevelValidation,
|
||||
} = props
|
||||
|
||||
const value = {
|
||||
formContextOnChange: formContextOnChange,
|
||||
values: values,
|
||||
errors: errors,
|
||||
handleBlur: handleBlur,
|
||||
touched: touched,
|
||||
fieldLevelValidation: fieldLevelValidation,
|
||||
}
|
||||
|
||||
return (
|
||||
<FormContext.Provider value={value}>{props.children}</FormContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
// context helper to avoid using a consumer component
|
||||
export const useFormContext = () => {
|
||||
const context = useContext(FormContext)
|
||||
if (context === undefined) {
|
||||
throw new Error(
|
||||
`useFormContextOnChange must be used within a FormContextProvider.`
|
||||
)
|
||||
}
|
||||
return context
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,281 @@
|
||||
[
|
||||
{
|
||||
"name": "Email",
|
||||
"icon": "email-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "email-app-id",
|
||||
"label": "email App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "email-id-key",
|
||||
"label": "email client ID",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "email-id-key",
|
||||
"label": "email client ID",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "email-id-key",
|
||||
"label": "email client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Phone",
|
||||
"icon": "phone-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "select",
|
||||
"name": "phone-app-provider",
|
||||
"label": "Phone service provider",
|
||||
"description": "You can use a provider etc etc"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "phone-id-key",
|
||||
"label": "phone client ID",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "phone-id-key",
|
||||
"label": "phone client ID",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "phone-id-key",
|
||||
"label": "phone client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Google",
|
||||
"icon": "google-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "google-app-id",
|
||||
"label": "Google App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "google-id-key",
|
||||
"label": "Google client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Facebook",
|
||||
"icon": "facebook-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "facebook-app-id",
|
||||
"label": "Facebook App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "facebook-id-key",
|
||||
"label": "Facebook client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Twitter",
|
||||
"icon": "twitter-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "twitter-app-id",
|
||||
"label": "Twitter App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "twitter-id-key",
|
||||
"label": "Twitter client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Apple",
|
||||
"icon": "apple-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "apple-app-id",
|
||||
"label": "Apple App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "apple-id-key",
|
||||
"label": "Apple client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Microsoft",
|
||||
"icon": "microsoft-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "microsoft-app-id",
|
||||
"label": "Microsoft App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "microsoft-id-key",
|
||||
"label": "Microsoft client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Gitlab",
|
||||
"icon": "gitlab-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "gitlab-app-id",
|
||||
"label": "Gitlab App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "gitlab-id-key",
|
||||
"label": "Gitlab client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Bitbucket",
|
||||
"icon": "bitbucket-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "bitbucket-app-id",
|
||||
"label": "Bitbucket App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "bitbucket-id-key",
|
||||
"label": "Bitbucket client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Discord",
|
||||
"icon": "discord-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "discord-app-id",
|
||||
"label": "Discord App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "discord-id-key",
|
||||
"label": "Discord client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Github",
|
||||
"icon": "github-icon-dark",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "github-app-id",
|
||||
"label": "Github App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "github-id-key",
|
||||
"label": "Github client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Slack",
|
||||
"icon": "slack-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "slack-app-id",
|
||||
"label": "Slack App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "slack-id-key",
|
||||
"label": "Slack client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Spotify",
|
||||
"icon": "spotify-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "spotify-app-id",
|
||||
"label": "Spotify App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "spotify-id-key",
|
||||
"label": "Spotify client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Twitch",
|
||||
"icon": "twitch-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "twitch-app-id",
|
||||
"label": "Twitch App Id",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "twitch-id-key",
|
||||
"label": "Twitch client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "Twilio",
|
||||
"icon": "twilio-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "twilio-app-id",
|
||||
"label": "Enable twilio Provider",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "twilio-id-key",
|
||||
"label": "twilio client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Messagebird",
|
||||
"icon": "messagebird-icon",
|
||||
"form": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "messagebird-app-id",
|
||||
"label": "Enable gitlab messagebird",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "messagebird-id-key",
|
||||
"label": "messagebird client ID",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Form } from './Form'
|
||||
@@ -0,0 +1,39 @@
|
||||
/* .sbui-icon-container {
|
||||
@apply flex-shrink-0 flex items-center justify-center rounded-full p-3;
|
||||
}
|
||||
|
||||
.sbui-icon-container--brand {
|
||||
@apply bg-brand-800 bg-opacity-10 text-brand-800;
|
||||
}
|
||||
|
||||
.sbui-icon-container--gray {
|
||||
@apply bg-gray-600 bg-opacity-10 text-gray-500;
|
||||
}
|
||||
|
||||
.sbui-icon-container--red {
|
||||
@apply bg-red-600 bg-opacity-10 text-red-500;
|
||||
}
|
||||
|
||||
.sbui-icon-container--yellow {
|
||||
@apply bg-yellow-600 bg-opacity-10 text-yellow-500;
|
||||
}
|
||||
|
||||
.sbui-icon-container--green {
|
||||
@apply bg-green-600 bg-opacity-10 text-green-500;
|
||||
}
|
||||
|
||||
.sbui-icon-container--blue {
|
||||
@apply bg-blue-600 bg-opacity-10 text-blue-500;
|
||||
}
|
||||
|
||||
.sbui-icon-container--indigo {
|
||||
@apply bg-indigo-600 bg-opacity-10 text-indigo-500;
|
||||
}
|
||||
|
||||
.sbui-icon-container--purple {
|
||||
@apply bg-purple-600 bg-opacity-10 text-purple-500;
|
||||
}
|
||||
|
||||
.sbui-icon-container--pink {
|
||||
@apply bg-pink-600 bg-opacity-10 text-pink-500;
|
||||
} */
|
||||
@@ -0,0 +1,66 @@
|
||||
import React from 'react'
|
||||
|
||||
import { IconMail, Typography } from './../../index'
|
||||
|
||||
export default {
|
||||
title: 'General/Icon',
|
||||
component: IconMail,
|
||||
}
|
||||
|
||||
export const Default = (args: any) => (
|
||||
<div className="block font-sans">
|
||||
<div>
|
||||
<Typography.Text>
|
||||
<IconMail {...args} />
|
||||
</Typography.Text>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Default.args = {
|
||||
size: 16,
|
||||
strokeWidth: 2,
|
||||
}
|
||||
|
||||
// export const IconList = (args: any) => (
|
||||
// <>
|
||||
// <div className="font-sans text-xl bg-blue-100 p-5 mb-3 rounded-md">
|
||||
// This icons uses react-feather from Feather Icons. For detail you can check
|
||||
// it <a href="https://github.com/feathericons/react-feather">here</a> and{' '}
|
||||
// <a href="https://feathericons.com/">here</a>
|
||||
// </div>
|
||||
// <div className="flex flex-wrap font-sans">
|
||||
// {LIST_ICONS.map((icon) => (
|
||||
// <div className="m-2 shadow-lg rounded-lg w-36 h-36 flex flex-col justify-center items-center dark:text-white">
|
||||
// <Icon type={icon} key={icon} {...args} />
|
||||
// <span className="mt-2">{icon}</span>
|
||||
// </div>
|
||||
// ))}
|
||||
// </div>
|
||||
// </>
|
||||
// )
|
||||
|
||||
// IconList.args = {
|
||||
// size: 16,
|
||||
// strokeWidth: 2,
|
||||
// }
|
||||
|
||||
// // const SvgMessagesIcon = () => (
|
||||
// // <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
// // <path
|
||||
// // stroke-linecap="round"
|
||||
// // stroke-linejoin="round"
|
||||
// // stroke-width="2"
|
||||
// // d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"
|
||||
// // />
|
||||
// // </svg>
|
||||
// // )
|
||||
|
||||
// // export const IconWithSVG = (args: any) => (
|
||||
// // <Icon {...args} src={<SvgMessagesIcon />} />
|
||||
// // )
|
||||
|
||||
// // IconWithSVG.args = {
|
||||
// // size: 'xxxlarge',
|
||||
// // strokeWidth: 4,
|
||||
// // }
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import Icon from './Icon'
|
||||
|
||||
describe('#Icon', () => {
|
||||
it('should render Icon correctly', () => {
|
||||
render(<Icon data-testid="icon" />)
|
||||
const $elIcon = screen.queryByTestId('icon')
|
||||
expect($elIcon).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should change svg size', () => {
|
||||
render(<Icon data-testid="icon" size={40} />)
|
||||
|
||||
const $elIcon = screen.queryByTestId('icon')
|
||||
expect($elIcon.getAttribute('width')).toEqual('40')
|
||||
expect($elIcon.getAttribute('height')).toEqual('40')
|
||||
})
|
||||
|
||||
it('should change strokeWidth value', () => {
|
||||
render(<Icon data-testid="icon" strokeWidth={1} />)
|
||||
|
||||
const $elIcon = screen.queryByTestId('icon')
|
||||
expect($elIcon.getAttribute('stroke-width')).toEqual('1')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,133 @@
|
||||
import React from 'react'
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
import { IconContext } from './IconContext'
|
||||
// @ts-ignore
|
||||
// import IconStyles from './Icon.module.css'
|
||||
|
||||
const IconStyles = {}
|
||||
|
||||
interface Props {
|
||||
className?: string
|
||||
size?:
|
||||
| 'tiny'
|
||||
| 'small'
|
||||
| 'medium'
|
||||
| 'large'
|
||||
| 'xlarge'
|
||||
| 'xxlarge'
|
||||
| 'xxxlarge'
|
||||
| number
|
||||
type?: string
|
||||
color?: string
|
||||
strokeWidth?: number
|
||||
fill?: string
|
||||
stroke?: string
|
||||
background?:
|
||||
| 'brand'
|
||||
| 'gray'
|
||||
| 'red'
|
||||
| 'yellow'
|
||||
| 'green'
|
||||
| 'blue'
|
||||
| 'indigo'
|
||||
| 'purple'
|
||||
| 'pink'
|
||||
src: React.ReactNode
|
||||
}
|
||||
|
||||
interface StringMap {
|
||||
[key: string]: number
|
||||
}
|
||||
|
||||
function Icon({
|
||||
className,
|
||||
size,
|
||||
type,
|
||||
color,
|
||||
strokeWidth,
|
||||
fill = undefined,
|
||||
stroke = undefined,
|
||||
background,
|
||||
src,
|
||||
...props
|
||||
}: Props) {
|
||||
const __styles = styleHandler('icon')
|
||||
|
||||
return (
|
||||
<IconContext.Consumer>
|
||||
{({ contextSize, className: contextClassName }) => {
|
||||
const defaultSizes: StringMap = {
|
||||
tiny: 14,
|
||||
small: 18,
|
||||
medium: 20,
|
||||
large: 20,
|
||||
xlarge: 24,
|
||||
xxlarge: 30,
|
||||
xxxlarge: 42,
|
||||
}
|
||||
|
||||
const defaultSize = defaultSizes['large']
|
||||
|
||||
// const iconSize = typeof size === 'string' ? defaultSizes[contextSize] : 21
|
||||
let iconSize: any = 21
|
||||
|
||||
// use contextSize of parent (via context hook) if one exists
|
||||
if (contextSize) {
|
||||
iconSize = contextSize
|
||||
? typeof contextSize === 'string'
|
||||
? defaultSizes[contextSize]
|
||||
: contextSize
|
||||
: defaultSize
|
||||
}
|
||||
|
||||
// use size prop of this component if one exists
|
||||
if (size) {
|
||||
iconSize = size
|
||||
? typeof size === 'string'
|
||||
? defaultSizes[size]
|
||||
: size
|
||||
: defaultSize
|
||||
}
|
||||
|
||||
// confitional used for Icons with no color settings
|
||||
// default these icons to use 'currentColor' ie, the text color
|
||||
const noColor = !color && !fill && !stroke
|
||||
|
||||
let classes = ['sbui-icon', className]
|
||||
if (contextClassName) {
|
||||
classes.push(contextClassName)
|
||||
}
|
||||
|
||||
const Icon = (
|
||||
// custom SVG file
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
color={!noColor ? color : 'currentColor'}
|
||||
fill={!noColor ? (fill ? fill : 'none') : 'none'}
|
||||
stroke={!noColor ? stroke : 'currentColor'}
|
||||
strokeWidth={strokeWidth}
|
||||
className={classes.join(' ')}
|
||||
width={iconSize}
|
||||
height={iconSize}
|
||||
{...props}
|
||||
>
|
||||
{src}
|
||||
</svg>
|
||||
)
|
||||
|
||||
return background ? (
|
||||
<div
|
||||
// circle coloured background
|
||||
className={__styles.container}
|
||||
>
|
||||
{Icon}
|
||||
</div>
|
||||
) : (
|
||||
Icon
|
||||
)
|
||||
}}
|
||||
</IconContext.Consumer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Icon
|
||||
@@ -0,0 +1,144 @@
|
||||
import React from 'react'
|
||||
import styleHandler from '../../lib/theme/styleHandler'
|
||||
import { IconContext } from './IconContext'
|
||||
// @ts-ignore
|
||||
// import IconStyles from './Icon.module.css'
|
||||
|
||||
interface Props {
|
||||
className?: string
|
||||
size?:
|
||||
| 'tiny'
|
||||
| 'small'
|
||||
| 'medium'
|
||||
| 'large'
|
||||
| 'xlarge'
|
||||
| 'xxlarge'
|
||||
| 'xxxlarge'
|
||||
| number
|
||||
type?: string
|
||||
color?: string
|
||||
strokeWidth?: number
|
||||
fill?: string
|
||||
stroke?: string
|
||||
background?:
|
||||
| 'brand'
|
||||
| 'gray'
|
||||
| 'red'
|
||||
| 'yellow'
|
||||
| 'green'
|
||||
| 'blue'
|
||||
| 'indigo'
|
||||
| 'purple'
|
||||
| 'pink'
|
||||
src?: React.ReactNode
|
||||
icon?: any
|
||||
}
|
||||
|
||||
interface StringMap {
|
||||
[key: string]: number
|
||||
}
|
||||
|
||||
function IconBase({
|
||||
className,
|
||||
size,
|
||||
type = 'Mail',
|
||||
color,
|
||||
strokeWidth,
|
||||
fill = undefined,
|
||||
stroke = undefined,
|
||||
background,
|
||||
src,
|
||||
icon,
|
||||
...props
|
||||
}: Props) {
|
||||
const __styles = styleHandler('icon')
|
||||
|
||||
return (
|
||||
<IconContext.Consumer>
|
||||
{({ contextSize, className: contextClassName }) => {
|
||||
const defaultSizes: StringMap = {
|
||||
tiny: 14,
|
||||
small: 18,
|
||||
medium: 20,
|
||||
large: 20,
|
||||
xlarge: 24,
|
||||
xxlarge: 30,
|
||||
xxxlarge: 42,
|
||||
}
|
||||
|
||||
const defaultSize = defaultSizes['large']
|
||||
// @ts-ignore
|
||||
|
||||
const FeatherIcon = icon
|
||||
|
||||
// const iconSize = typeof size === 'string' ? defaultSizes[contextSize] : 21
|
||||
let iconSize: any = 21
|
||||
|
||||
// use contextSize of parent (via context hook) if one exists
|
||||
if (contextSize) {
|
||||
iconSize = contextSize
|
||||
? typeof contextSize === 'string'
|
||||
? defaultSizes[contextSize]
|
||||
: contextSize
|
||||
: defaultSize
|
||||
}
|
||||
|
||||
// use size prop of this component if one exists
|
||||
if (size) {
|
||||
iconSize = size
|
||||
? typeof size === 'string'
|
||||
? defaultSizes[size]
|
||||
: size
|
||||
: defaultSize
|
||||
}
|
||||
|
||||
// confitional used for Icons with no color settings
|
||||
// default these icons to use 'currentColor' ie, the text color
|
||||
const noColor = !color && !fill && !stroke
|
||||
|
||||
let classes = ['sbui-icon', className]
|
||||
if (contextClassName) {
|
||||
classes.push(contextClassName)
|
||||
}
|
||||
|
||||
const IconComponent = () => (
|
||||
<FeatherIcon
|
||||
color={!noColor ? color : 'currentColor'}
|
||||
stroke={!noColor ? stroke : 'currentColor'}
|
||||
className={classes.join(' ')}
|
||||
strokeWidth={strokeWidth}
|
||||
size={iconSize}
|
||||
fill={!noColor ? (fill ? fill : 'none') : 'none'}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
const Icon = src ? (
|
||||
// custom SVG file
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
color={!noColor ? color : 'currentColor'}
|
||||
fill={!noColor ? (fill ? fill : 'none') : 'none'}
|
||||
stroke={!noColor ? stroke : 'currentColor'}
|
||||
className={classes.join(' ')}
|
||||
width={iconSize}
|
||||
height={iconSize}
|
||||
>
|
||||
{src}
|
||||
</svg>
|
||||
) : (
|
||||
// feather icon
|
||||
<IconComponent />
|
||||
)
|
||||
|
||||
return background ? (
|
||||
<div className={__styles.container}>{Icon}</div>
|
||||
) : (
|
||||
Icon
|
||||
)
|
||||
}}
|
||||
</IconContext.Consumer>
|
||||
)
|
||||
}
|
||||
|
||||
export default IconBase
|
||||
@@ -0,0 +1,10 @@
|
||||
import { createContext } from 'react'
|
||||
|
||||
type ContextValue = { contextSize?: string; className?: string }
|
||||
|
||||
// Make sure the shape of the default value passed to
|
||||
// createContext matches the shape that the consumers expect!
|
||||
export const IconContext = createContext<ContextValue>({
|
||||
contextSize: '',
|
||||
className: '',
|
||||
})
|
||||
@@ -0,0 +1,294 @@
|
||||
import { FC, SVGAttributes } from 'react'
|
||||
|
||||
export interface IconProps extends SVGAttributes<SVGElement> {
|
||||
color?: string
|
||||
size?: string | number
|
||||
}
|
||||
|
||||
export type Icon = FC<IconProps>
|
||||
export const Activity: Icon = require(`react-feather/dist/icons/activity`)
|
||||
export const Airplay: Icon = require(`react-feather/dist/icons/airplay`)
|
||||
export const AlertCircle: Icon = require(`react-feather/dist/icons/alert-circle`)
|
||||
export const AlertOctagon: Icon = require(`react-feather/dist/icons/alert-octagon`)
|
||||
export const AlertTriangle: Icon = require(`react-feather/dist/icons/alert-triangle`)
|
||||
export const AlignCenter: Icon = require(`react-feather/dist/icons/align-center`)
|
||||
export const AlignJustify: Icon = require(`react-feather/dist/icons/align-justify`)
|
||||
export const AlignLeft: Icon = require(`react-feather/dist/icons/align-left`)
|
||||
export const AlignRight: Icon = require(`react-feather/dist/icons/align-right`)
|
||||
export const Anchor: Icon = require(`react-feather/dist/icons/anchor`)
|
||||
export const Aperture: Icon = require(`react-feather/dist/icons/aperture`)
|
||||
export const Archive: Icon = require(`react-feather/dist/icons/archive`)
|
||||
export const ArrowDownCircle: Icon = require(`react-feather/dist/icons/arrow-down-circle`)
|
||||
export const ArrowDownLeft: Icon = require(`react-feather/dist/icons/arrow-down-left`)
|
||||
export const ArrowDownRight: Icon = require(`react-feather/dist/icons/arrow-down-right`)
|
||||
export const ArrowDown: Icon = require(`react-feather/dist/icons/arrow-down`)
|
||||
export const ArrowLeftCircle: Icon = require(`react-feather/dist/icons/arrow-left-circle`)
|
||||
export const ArrowLeft: Icon = require(`react-feather/dist/icons/arrow-left`)
|
||||
export const ArrowRightCircle: Icon = require(`react-feather/dist/icons/arrow-right-circle`)
|
||||
export const ArrowRight: Icon = require(`react-feather/dist/icons/arrow-right`)
|
||||
export const ArrowUpCircle: Icon = require(`react-feather/dist/icons/arrow-up-circle`)
|
||||
export const ArrowUpLeft: Icon = require(`react-feather/dist/icons/arrow-up-left`)
|
||||
export const ArrowUpRight: Icon = require(`react-feather/dist/icons/arrow-up-right`)
|
||||
export const ArrowUp: Icon = require(`react-feather/dist/icons/arrow-up`)
|
||||
export const AtSign: Icon = require(`react-feather/dist/icons/at-sign`)
|
||||
export const Award: Icon = require(`react-feather/dist/icons/award`)
|
||||
export const BarChart2: Icon = require(`react-feather/dist/icons/bar-chart-2`)
|
||||
export const BarChart: Icon = require(`react-feather/dist/icons/bar-chart`)
|
||||
export const BatteryCharging: Icon = require(`react-feather/dist/icons/battery-charging`)
|
||||
export const Battery: Icon = require(`react-feather/dist/icons/battery`)
|
||||
export const BellOff: Icon = require(`react-feather/dist/icons/bell-off`)
|
||||
export const Bell: Icon = require(`react-feather/dist/icons/bell`)
|
||||
export const Bluetooth: Icon = require(`react-feather/dist/icons/bluetooth`)
|
||||
export const Bold: Icon = require(`react-feather/dist/icons/bold`)
|
||||
export const BookOpen: Icon = require(`react-feather/dist/icons/book-open`)
|
||||
export const Book: Icon = require(`react-feather/dist/icons/book`)
|
||||
export const Bookmark: Icon = require(`react-feather/dist/icons/bookmark`)
|
||||
export const Box: Icon = require(`react-feather/dist/icons/box`)
|
||||
export const Briefcase: Icon = require(`react-feather/dist/icons/briefcase`)
|
||||
export const Calendar: Icon = require(`react-feather/dist/icons/calendar`)
|
||||
export const CameraOff: Icon = require(`react-feather/dist/icons/camera-off`)
|
||||
export const Camera: Icon = require(`react-feather/dist/icons/camera`)
|
||||
export const Cast: Icon = require(`react-feather/dist/icons/cast`)
|
||||
export const CheckCircle: Icon = require(`react-feather/dist/icons/check-circle`)
|
||||
export const CheckSquare: Icon = require(`react-feather/dist/icons/check-square`)
|
||||
export const Check: Icon = require(`react-feather/dist/icons/check`)
|
||||
export const ChevronDown: Icon = require(`react-feather/dist/icons/chevron-down`)
|
||||
export const ChevronLeft: Icon = require(`react-feather/dist/icons/chevron-left`)
|
||||
export const ChevronRight: Icon = require(`react-feather/dist/icons/chevron-right`)
|
||||
export const ChevronUp: Icon = require(`react-feather/dist/icons/chevron-up`)
|
||||
export const ChevronsDown: Icon = require(`react-feather/dist/icons/chevrons-down`)
|
||||
export const ChevronsLeft: Icon = require(`react-feather/dist/icons/chevrons-left`)
|
||||
export const ChevronsRight: Icon = require(`react-feather/dist/icons/chevrons-right`)
|
||||
export const ChevronsUp: Icon = require(`react-feather/dist/icons/chevrons-up`)
|
||||
export const Chrome: Icon = require(`react-feather/dist/icons/chrome`)
|
||||
export const Circle: Icon = require(`react-feather/dist/icons/circle`)
|
||||
export const Clipboard: Icon = require(`react-feather/dist/icons/clipboard`)
|
||||
export const Clock: Icon = require(`react-feather/dist/icons/clock`)
|
||||
export const CloudDrizzle: Icon = require(`react-feather/dist/icons/cloud-drizzle`)
|
||||
export const CloudLightning: Icon = require(`react-feather/dist/icons/cloud-lightning`)
|
||||
export const CloudOff: Icon = require(`react-feather/dist/icons/cloud-off`)
|
||||
export const CloudRain: Icon = require(`react-feather/dist/icons/cloud-rain`)
|
||||
export const CloudSnow: Icon = require(`react-feather/dist/icons/cloud-snow`)
|
||||
export const Cloud: Icon = require(`react-feather/dist/icons/cloud`)
|
||||
export const Code: Icon = require(`react-feather/dist/icons/code`)
|
||||
export const Codepen: Icon = require(`react-feather/dist/icons/codepen`)
|
||||
export const Codesandbox: Icon = require(`react-feather/dist/icons/codesandbox`)
|
||||
export const Coffee: Icon = require(`react-feather/dist/icons/coffee`)
|
||||
export const Columns: Icon = require(`react-feather/dist/icons/columns`)
|
||||
export const Command: Icon = require(`react-feather/dist/icons/command`)
|
||||
export const Compass: Icon = require(`react-feather/dist/icons/compass`)
|
||||
export const Copy: Icon = require(`react-feather/dist/icons/copy`)
|
||||
export const CornerDownLeft: Icon = require(`react-feather/dist/icons/corner-down-left`)
|
||||
export const CornerDownRight: Icon = require(`react-feather/dist/icons/corner-down-right`)
|
||||
export const CornerLeftDown: Icon = require(`react-feather/dist/icons/corner-left-down`)
|
||||
export const CornerLeftUp: Icon = require(`react-feather/dist/icons/corner-left-up`)
|
||||
export const CornerRightDown: Icon = require(`react-feather/dist/icons/corner-right-down`)
|
||||
export const CornerRightUp: Icon = require(`react-feather/dist/icons/corner-right-up`)
|
||||
export const CornerUpLeft: Icon = require(`react-feather/dist/icons/corner-up-left`)
|
||||
export const CornerUpRight: Icon = require(`react-feather/dist/icons/corner-up-right`)
|
||||
export const Cpu: Icon = require(`react-feather/dist/icons/cpu`)
|
||||
export const CreditCard: Icon = require(`react-feather/dist/icons/credit-card`)
|
||||
export const Crop: Icon = require(`react-feather/dist/icons/crop`)
|
||||
export const Crosshair: Icon = require(`react-feather/dist/icons/crosshair`)
|
||||
export const Database: Icon = require(`react-feather/dist/icons/database`)
|
||||
export const Delete: Icon = require(`react-feather/dist/icons/delete`)
|
||||
export const Disc: Icon = require(`react-feather/dist/icons/disc`)
|
||||
export const DivideCircle: Icon = require(`react-feather/dist/icons/divide-circle`)
|
||||
export const DivideSquare: Icon = require(`react-feather/dist/icons/divide-square`)
|
||||
export const Divide: Icon = require(`react-feather/dist/icons/divide`)
|
||||
export const DollarSign: Icon = require(`react-feather/dist/icons/dollar-sign`)
|
||||
export const DownloadCloud: Icon = require(`react-feather/dist/icons/download-cloud`)
|
||||
export const Download: Icon = require(`react-feather/dist/icons/download`)
|
||||
export const Dribbble: Icon = require(`react-feather/dist/icons/dribbble`)
|
||||
export const Droplet: Icon = require(`react-feather/dist/icons/droplet`)
|
||||
export const Edit2: Icon = require(`react-feather/dist/icons/edit-2`)
|
||||
export const Edit3: Icon = require(`react-feather/dist/icons/edit-3`)
|
||||
export const Edit: Icon = require(`react-feather/dist/icons/edit`)
|
||||
export const ExternalLink: Icon = require(`react-feather/dist/icons/external-link`)
|
||||
export const EyeOff: Icon = require(`react-feather/dist/icons/eye-off`)
|
||||
export const Eye: Icon = require(`react-feather/dist/icons/eye`)
|
||||
export const Facebook: Icon = require(`react-feather/dist/icons/facebook`)
|
||||
export const FastForward: Icon = require(`react-feather/dist/icons/fast-forward`)
|
||||
export const Feather: Icon = require(`react-feather/dist/icons/feather`)
|
||||
export const Figma: Icon = require(`react-feather/dist/icons/figma`)
|
||||
export const FileMinus: Icon = require(`react-feather/dist/icons/file-minus`)
|
||||
export const FilePlus: Icon = require(`react-feather/dist/icons/file-plus`)
|
||||
export const FileText: Icon = require(`react-feather/dist/icons/file-text`)
|
||||
export const File: Icon = require(`react-feather/dist/icons/file`)
|
||||
export const Film: Icon = require(`react-feather/dist/icons/film`)
|
||||
export const Filter: Icon = require(`react-feather/dist/icons/filter`)
|
||||
export const Flag: Icon = require(`react-feather/dist/icons/flag`)
|
||||
export const FolderMinus: Icon = require(`react-feather/dist/icons/folder-minus`)
|
||||
export const FolderPlus: Icon = require(`react-feather/dist/icons/folder-plus`)
|
||||
export const Folder: Icon = require(`react-feather/dist/icons/folder`)
|
||||
export const Framer: Icon = require(`react-feather/dist/icons/framer`)
|
||||
export const Frown: Icon = require(`react-feather/dist/icons/frown`)
|
||||
export const Gift: Icon = require(`react-feather/dist/icons/gift`)
|
||||
export const GitBranch: Icon = require(`react-feather/dist/icons/git-branch`)
|
||||
export const GitCommit: Icon = require(`react-feather/dist/icons/git-commit`)
|
||||
export const GitMerge: Icon = require(`react-feather/dist/icons/git-merge`)
|
||||
export const GitPullRequest: Icon = require(`react-feather/dist/icons/git-pull-request`)
|
||||
export const GitHub: Icon = require(`react-feather/dist/icons/github`)
|
||||
export const Gitlab: Icon = require(`react-feather/dist/icons/gitlab`)
|
||||
export const Globe: Icon = require(`react-feather/dist/icons/globe`)
|
||||
export const Grid: Icon = require(`react-feather/dist/icons/grid`)
|
||||
export const HardDrive: Icon = require(`react-feather/dist/icons/hard-drive`)
|
||||
export const Hash: Icon = require(`react-feather/dist/icons/hash`)
|
||||
export const Headphones: Icon = require(`react-feather/dist/icons/headphones`)
|
||||
export const Heart: Icon = require(`react-feather/dist/icons/heart`)
|
||||
export const HelpCircle: Icon = require(`react-feather/dist/icons/help-circle`)
|
||||
export const Hexagon: Icon = require(`react-feather/dist/icons/hexagon`)
|
||||
export const Home: Icon = require(`react-feather/dist/icons/home`)
|
||||
export const Image: Icon = require(`react-feather/dist/icons/image`)
|
||||
export const Inbox: Icon = require(`react-feather/dist/icons/inbox`)
|
||||
export const Info: Icon = require(`react-feather/dist/icons/info`)
|
||||
export const Instagram: Icon = require(`react-feather/dist/icons/instagram`)
|
||||
export const Italic: Icon = require(`react-feather/dist/icons/italic`)
|
||||
export const Key: Icon = require(`react-feather/dist/icons/key`)
|
||||
export const Layers: Icon = require(`react-feather/dist/icons/layers`)
|
||||
export const Layout: Icon = require(`react-feather/dist/icons/layout`)
|
||||
export const LifeBuoy: Icon = require(`react-feather/dist/icons/life-buoy`)
|
||||
export const Link2: Icon = require(`react-feather/dist/icons/link-2`)
|
||||
export const Link: Icon = require(`react-feather/dist/icons/link`)
|
||||
export const Linkedin: Icon = require(`react-feather/dist/icons/linkedin`)
|
||||
export const List: Icon = require(`react-feather/dist/icons/list`)
|
||||
export const Loader: Icon = require(`react-feather/dist/icons/loader`)
|
||||
export const Lock: Icon = require(`react-feather/dist/icons/lock`)
|
||||
export const LogIn: Icon = require(`react-feather/dist/icons/log-in`)
|
||||
export const LogOut: Icon = require(`react-feather/dist/icons/log-out`)
|
||||
export const Mail: Icon = require(`react-feather/dist/icons/mail`)
|
||||
export const MapPin: Icon = require(`react-feather/dist/icons/map-pin`)
|
||||
export const Map: Icon = require(`react-feather/dist/icons/map`)
|
||||
export const Maximize2: Icon = require(`react-feather/dist/icons/maximize-2`)
|
||||
export const Maximize: Icon = require(`react-feather/dist/icons/maximize`)
|
||||
export const Meh: Icon = require(`react-feather/dist/icons/meh`)
|
||||
export const Menu: Icon = require(`react-feather/dist/icons/menu`)
|
||||
export const MessageCircle: Icon = require(`react-feather/dist/icons/message-circle`)
|
||||
export const MessageSquare: Icon = require(`react-feather/dist/icons/message-square`)
|
||||
export const MicOff: Icon = require(`react-feather/dist/icons/mic-off`)
|
||||
export const Mic: Icon = require(`react-feather/dist/icons/mic`)
|
||||
export const Minimize2: Icon = require(`react-feather/dist/icons/minimize-2`)
|
||||
export const Minimize: Icon = require(`react-feather/dist/icons/minimize`)
|
||||
export const MinusCircle: Icon = require(`react-feather/dist/icons/minus-circle`)
|
||||
export const MinusSquare: Icon = require(`react-feather/dist/icons/minus-square`)
|
||||
export const Minus: Icon = require(`react-feather/dist/icons/minus`)
|
||||
export const Monitor: Icon = require(`react-feather/dist/icons/monitor`)
|
||||
export const Moon: Icon = require(`react-feather/dist/icons/moon`)
|
||||
export const MoreHorizontal: Icon = require(`react-feather/dist/icons/more-horizontal`)
|
||||
export const MoreVertical: Icon = require(`react-feather/dist/icons/more-vertical`)
|
||||
export const MousePointer: Icon = require(`react-feather/dist/icons/mouse-pointer`)
|
||||
export const Move: Icon = require(`react-feather/dist/icons/move`)
|
||||
export const Music: Icon = require(`react-feather/dist/icons/music`)
|
||||
export const Navigation2: Icon = require(`react-feather/dist/icons/navigation-2`)
|
||||
export const Navigation: Icon = require(`react-feather/dist/icons/navigation`)
|
||||
export const Octagon: Icon = require(`react-feather/dist/icons/octagon`)
|
||||
export const Package: Icon = require(`react-feather/dist/icons/package`)
|
||||
export const Paperclip: Icon = require(`react-feather/dist/icons/paperclip`)
|
||||
export const PauseCircle: Icon = require(`react-feather/dist/icons/pause-circle`)
|
||||
export const Pause: Icon = require(`react-feather/dist/icons/pause`)
|
||||
export const PenTool: Icon = require(`react-feather/dist/icons/pen-tool`)
|
||||
export const Percent: Icon = require(`react-feather/dist/icons/percent`)
|
||||
export const PhoneCall: Icon = require(`react-feather/dist/icons/phone-call`)
|
||||
export const PhoneForwarded: Icon = require(`react-feather/dist/icons/phone-forwarded`)
|
||||
export const PhoneIncoming: Icon = require(`react-feather/dist/icons/phone-incoming`)
|
||||
export const PhoneMissed: Icon = require(`react-feather/dist/icons/phone-missed`)
|
||||
export const PhoneOff: Icon = require(`react-feather/dist/icons/phone-off`)
|
||||
export const PhoneOutgoing: Icon = require(`react-feather/dist/icons/phone-outgoing`)
|
||||
export const Phone: Icon = require(`react-feather/dist/icons/phone`)
|
||||
export const PieChart: Icon = require(`react-feather/dist/icons/pie-chart`)
|
||||
export const PlayCircle: Icon = require(`react-feather/dist/icons/play-circle`)
|
||||
export const Play: Icon = require(`react-feather/dist/icons/play`)
|
||||
export const PlusCircle: Icon = require(`react-feather/dist/icons/plus-circle`)
|
||||
export const PlusSquare: Icon = require(`react-feather/dist/icons/plus-square`)
|
||||
export const Plus: Icon = require(`react-feather/dist/icons/plus`)
|
||||
export const Pocket: Icon = require(`react-feather/dist/icons/pocket`)
|
||||
export const Power: Icon = require(`react-feather/dist/icons/power`)
|
||||
export const Printer: Icon = require(`react-feather/dist/icons/printer`)
|
||||
export const Radio: Icon = require(`react-feather/dist/icons/radio`)
|
||||
export const RefreshCcw: Icon = require(`react-feather/dist/icons/refresh-ccw`)
|
||||
export const RefreshCw: Icon = require(`react-feather/dist/icons/refresh-cw`)
|
||||
export const Repeat: Icon = require(`react-feather/dist/icons/repeat`)
|
||||
export const Rewind: Icon = require(`react-feather/dist/icons/rewind`)
|
||||
export const RotateCcw: Icon = require(`react-feather/dist/icons/rotate-ccw`)
|
||||
export const RotateCw: Icon = require(`react-feather/dist/icons/rotate-cw`)
|
||||
export const Rss: Icon = require(`react-feather/dist/icons/rss`)
|
||||
export const Save: Icon = require(`react-feather/dist/icons/save`)
|
||||
export const Scissors: Icon = require(`react-feather/dist/icons/scissors`)
|
||||
export const Search: Icon = require(`react-feather/dist/icons/search`)
|
||||
export const Send: Icon = require(`react-feather/dist/icons/send`)
|
||||
export const Server: Icon = require(`react-feather/dist/icons/server`)
|
||||
export const Settings: Icon = require(`react-feather/dist/icons/settings`)
|
||||
export const Share2: Icon = require(`react-feather/dist/icons/share-2`)
|
||||
export const Share: Icon = require(`react-feather/dist/icons/share`)
|
||||
export const ShieldOff: Icon = require(`react-feather/dist/icons/shield-off`)
|
||||
export const Shield: Icon = require(`react-feather/dist/icons/shield`)
|
||||
export const ShoppingBag: Icon = require(`react-feather/dist/icons/shopping-bag`)
|
||||
export const ShoppingCart: Icon = require(`react-feather/dist/icons/shopping-cart`)
|
||||
export const Shuffle: Icon = require(`react-feather/dist/icons/shuffle`)
|
||||
export const Sidebar: Icon = require(`react-feather/dist/icons/sidebar`)
|
||||
export const SkipBack: Icon = require(`react-feather/dist/icons/skip-back`)
|
||||
export const SkipForward: Icon = require(`react-feather/dist/icons/skip-forward`)
|
||||
export const Slack: Icon = require(`react-feather/dist/icons/slack`)
|
||||
export const Slash: Icon = require(`react-feather/dist/icons/slash`)
|
||||
export const Sliders: Icon = require(`react-feather/dist/icons/sliders`)
|
||||
export const Smartphone: Icon = require(`react-feather/dist/icons/smartphone`)
|
||||
export const Smile: Icon = require(`react-feather/dist/icons/smile`)
|
||||
export const Speaker: Icon = require(`react-feather/dist/icons/speaker`)
|
||||
export const Square: Icon = require(`react-feather/dist/icons/square`)
|
||||
export const Star: Icon = require(`react-feather/dist/icons/star`)
|
||||
export const StopCircle: Icon = require(`react-feather/dist/icons/stop-circle`)
|
||||
export const Sun: Icon = require(`react-feather/dist/icons/sun`)
|
||||
export const Sunrise: Icon = require(`react-feather/dist/icons/sunrise`)
|
||||
export const Sunset: Icon = require(`react-feather/dist/icons/sunset`)
|
||||
export const Tablet: Icon = require(`react-feather/dist/icons/tablet`)
|
||||
export const Tag: Icon = require(`react-feather/dist/icons/tag`)
|
||||
export const Target: Icon = require(`react-feather/dist/icons/target`)
|
||||
export const Terminal: Icon = require(`react-feather/dist/icons/terminal`)
|
||||
export const Thermometer: Icon = require(`react-feather/dist/icons/thermometer`)
|
||||
export const ThumbsDown: Icon = require(`react-feather/dist/icons/thumbs-down`)
|
||||
export const ThumbsUp: Icon = require(`react-feather/dist/icons/thumbs-up`)
|
||||
export const ToggleLeft: Icon = require(`react-feather/dist/icons/toggle-left`)
|
||||
export const ToggleRight: Icon = require(`react-feather/dist/icons/toggle-right`)
|
||||
export const Tool: Icon = require(`react-feather/dist/icons/tool`)
|
||||
export const Trash2: Icon = require(`react-feather/dist/icons/trash-2`)
|
||||
export const Trash: Icon = require(`react-feather/dist/icons/trash`)
|
||||
export const Trello: Icon = require(`react-feather/dist/icons/trello`)
|
||||
export const TrendingDown: Icon = require(`react-feather/dist/icons/trending-down`)
|
||||
export const TrendingUp: Icon = require(`react-feather/dist/icons/trending-up`)
|
||||
export const Triangle: Icon = require(`react-feather/dist/icons/triangle`)
|
||||
export const Truck: Icon = require(`react-feather/dist/icons/truck`)
|
||||
export const Tv: Icon = require(`react-feather/dist/icons/tv`)
|
||||
export const Twitch: Icon = require(`react-feather/dist/icons/twitch`)
|
||||
export const Twitter: Icon = require(`react-feather/dist/icons/twitter`)
|
||||
export const Type: Icon = require(`react-feather/dist/icons/type`)
|
||||
export const Umbrella: Icon = require(`react-feather/dist/icons/umbrella`)
|
||||
export const Underline: Icon = require(`react-feather/dist/icons/underline`)
|
||||
export const Unlock: Icon = require(`react-feather/dist/icons/unlock`)
|
||||
export const UploadCloud: Icon = require(`react-feather/dist/icons/upload-cloud`)
|
||||
export const Upload: Icon = require(`react-feather/dist/icons/upload`)
|
||||
export const UserCheck: Icon = require(`react-feather/dist/icons/user-check`)
|
||||
export const UserMinus: Icon = require(`react-feather/dist/icons/user-minus`)
|
||||
export const UserPlus: Icon = require(`react-feather/dist/icons/user-plus`)
|
||||
export const UserX: Icon = require(`react-feather/dist/icons/user-x`)
|
||||
export const User: Icon = require(`react-feather/dist/icons/user`)
|
||||
export const Users: Icon = require(`react-feather/dist/icons/users`)
|
||||
export const VideoOff: Icon = require(`react-feather/dist/icons/video-off`)
|
||||
export const Video: Icon = require(`react-feather/dist/icons/video`)
|
||||
export const Voicemail: Icon = require(`react-feather/dist/icons/voicemail`)
|
||||
export const Volume1: Icon = require(`react-feather/dist/icons/volume-1`)
|
||||
export const Volume2: Icon = require(`react-feather/dist/icons/volume-2`)
|
||||
export const VolumeX: Icon = require(`react-feather/dist/icons/volume-x`)
|
||||
export const Volume: Icon = require(`react-feather/dist/icons/volume`)
|
||||
export const Watch: Icon = require(`react-feather/dist/icons/watch`)
|
||||
export const WifiOff: Icon = require(`react-feather/dist/icons/wifi-off`)
|
||||
export const Wifi: Icon = require(`react-feather/dist/icons/wifi`)
|
||||
export const Wind: Icon = require(`react-feather/dist/icons/wind`)
|
||||
export const XCircle: Icon = require(`react-feather/dist/icons/x-circle`)
|
||||
export const XOctagon: Icon = require(`react-feather/dist/icons/x-octagon`)
|
||||
export const XSquare: Icon = require(`react-feather/dist/icons/x-square`)
|
||||
export const X: Icon = require(`react-feather/dist/icons/x`)
|
||||
export const Youtube: Icon = require(`react-feather/dist/icons/youtube`)
|
||||
export const ZapOff: Icon = require(`react-feather/dist/icons/zap-off`)
|
||||
export const Zap: Icon = require(`react-feather/dist/icons/zap`)
|
||||
export const ZoomIn: Icon = require(`react-feather/dist/icons/zoom-in`)
|
||||
export const ZoomOut: Icon = require(`react-feather/dist/icons/zoom-out`)
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { Activity } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconActivity(props: any) {
|
||||
return <IconBase icon={Activity} {...props} />
|
||||
}
|
||||
|
||||
export default IconActivity
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconActivity } from './IconActivity'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { Airplay } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAirplay(props: any) {
|
||||
return <IconBase icon={Airplay} {...props} />
|
||||
}
|
||||
|
||||
export default IconAirplay
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAirplay } from './IconAirplay'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { AlertCircle } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAlertCircle(props: any) {
|
||||
return <IconBase icon={AlertCircle} {...props} />
|
||||
}
|
||||
|
||||
export default IconAlertCircle
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAlertCircle } from './IconAlertCircle'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { AlertOctagon } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAlertOctagon(props: any) {
|
||||
return <IconBase icon={AlertOctagon} {...props} />
|
||||
}
|
||||
|
||||
export default IconAlertOctagon
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAlertOctagon } from './IconAlertOctagon'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { AlertTriangle } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAlertTriangle(props: any) {
|
||||
return <IconBase icon={AlertTriangle} {...props} />
|
||||
}
|
||||
|
||||
export default IconAlertTriangle
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAlertTriangle } from './IconAlertTriangle'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { AlignCenter } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAlignCenter(props: any) {
|
||||
return <IconBase icon={AlignCenter} {...props} />
|
||||
}
|
||||
|
||||
export default IconAlignCenter
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAlignCenter } from './IconAlignCenter'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { AlignJustify } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAlignJustify(props: any) {
|
||||
return <IconBase icon={AlignJustify} {...props} />
|
||||
}
|
||||
|
||||
export default IconAlignJustify
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAlignJustify } from './IconAlignJustify'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { AlignLeft } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAlignLeft(props: any) {
|
||||
return <IconBase icon={AlignLeft} {...props} />
|
||||
}
|
||||
|
||||
export default IconAlignLeft
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAlignLeft } from './IconAlignLeft'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { AlignRight } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAlignRight(props: any) {
|
||||
return <IconBase icon={AlignRight} {...props} />
|
||||
}
|
||||
|
||||
export default IconAlignRight
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAlignRight } from './IconAlignRight'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { Anchor } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAnchor(props: any) {
|
||||
return <IconBase icon={Anchor} {...props} />
|
||||
}
|
||||
|
||||
export default IconAnchor
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as IconAnchor } from './IconAnchor'
|
||||
@@ -0,0 +1,13 @@
|
||||
// DO NOT EDIT
|
||||
// this file is generated by /internals/populate-icons script
|
||||
import * as React from 'react'
|
||||
// @ts-ignore
|
||||
import { Aperture } from 'react-feather'
|
||||
import IconBase from './../../IconBase'
|
||||
|
||||
function IconAperture(props: any) {
|
||||
return <IconBase icon={Aperture} {...props} />
|
||||
}
|
||||
|
||||
export default IconAperture
|
||||
|
||||
Loaded 100 of 1130 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user