Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
30f65443
Commit
30f65443
authored
Jan 14, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
styles for floating input
parent
3a55206a
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
376 additions
and
3 deletions
+376
-3
field.tsx
toolkit/chakra/field.tsx
+35
-3
input.tsx
toolkit/chakra/input.tsx
+6
-0
semanticTokens.ts
toolkit/theme/foundations/semanticTokens.ts
+27
-0
field.recipe.ts
toolkit/theme/recipes/field.recipe.ts
+138
-0
index.ts
toolkit/theme/recipes/index.ts
+4
-0
input.recipe.ts
toolkit/theme/recipes/input.recipe.ts
+108
-0
Chakra.tsx
ui/pages/Chakra.tsx
+58
-0
No files found.
toolkit/chakra/field.tsx
View file @
30f65443
import
{
Field
as
ChakraField
}
from
'
@chakra-ui/react
'
;
import
*
as
React
from
'
react
'
;
export
interface
FieldProps
extends
Omit
<
ChakraField
.
RootProps
,
'
label
'
>
{
import
{
space
}
from
'
lib/html-entities
'
;
import
type
{
InputProps
}
from
'
./input
'
;
export
interface
FieldProps
extends
Omit
<
ChakraField
.
RootProps
,
'
label
'
|
'
children
'
>
{
label
?:
React
.
ReactNode
;
helperText
?:
React
.
ReactNode
;
errorText
?:
React
.
ReactNode
;
optionalText
?:
React
.
ReactNode
;
children
:
React
.
ReactElement
<
InputProps
>
;
}
export
const
Field
=
React
.
forwardRef
<
HTMLDivElement
,
FieldProps
>
(
function
Field
(
props
,
ref
)
{
const
{
label
,
children
,
helperText
,
errorText
,
optionalText
,
...
rest
}
=
props
;
const
{
label
,
children
,
helperText
,
errorText
,
optionalText
,
...
rest
}
=
props
;
// A floating field cannot be without a label.
if
(
props
.
floating
&&
label
)
{
const
child
=
React
.
Children
.
only
<
React
.
ReactElement
<
InputProps
>>
(
children
);
const
clonedChild
=
React
.
cloneElement
(
child
,
{
className
:
'
peer
'
,
placeholder
:
'
'
,
size
:
props
.
size
,
floating
:
props
.
floating
,
});
return
(
<
ChakraField
.
Root
pos=
"relative"
w=
"full"
ref=
{
ref
}
{
...
rest
}
>
{
clonedChild
}
<
ChakraField
.
Label
>
{
label
}
<
ChakraField
.
RequiredIndicator
fallback=
{
optionalText
}
/>
{
errorText
&&
(
<
ChakraField
.
ErrorText
ml=
"2px"
>
-
{
space
}{
errorText
}
</
ChakraField
.
ErrorText
>
)
}
</
ChakraField
.
Label
>
{
helperText
&&
(
<
ChakraField
.
HelperText
>
{
helperText
}
</
ChakraField
.
HelperText
>
)
}
</
ChakraField
.
Root
>
);
}
return
(
<
ChakraField
.
Root
ref=
{
ref
}
{
...
rest
}
>
{
label
&&
(
...
...
toolkit/chakra/input.tsx
0 → 100644
View file @
30f65443
import
type
{
InputProps
as
ChakraInputProps
}
from
'
@chakra-ui/react
'
;
import
{
Input
as
ChakraInput
}
from
'
@chakra-ui/react
'
;
export
interface
InputProps
extends
ChakraInputProps
{}
export
const
Input
=
ChakraInput
;
toolkit/theme/foundations/semanticTokens.ts
View file @
30f65443
...
...
@@ -138,12 +138,39 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
neutral
:
{
value
:
{
_light
:
'
{colors.blackAlpha.50}
'
,
_dark
:
'
{colors.whiteAlpha.100}
'
}
},
},
},
input
:
{
fg
:
{
DEFAULT
:
{
value
:
{
_light
:
'
{colors.blue.800}
'
,
_dark
:
'
{colors.gray.50}
'
}
},
error
:
{
value
:
'
{colors.text.error}
'
},
},
bg
:
{
DEFAULT
:
{
value
:
{
_light
:
'
{colors.white}
'
,
_dark
:
'
{colors.black}
'
}
},
readOnly
:
{
value
:
{
_light
:
'
{colors.gray.200}
'
,
_dark
:
'
{colors.gray.800}
'
}
},
},
border
:
{
DEFAULT
:
{
value
:
{
_light
:
'
{colors.gray.100}
'
,
_dark
:
'
{colors.gray.700}
'
}
},
hover
:
{
value
:
{
_light
:
'
{colors.gray.200}
'
,
_dark
:
'
{colors.gray.500}
'
}
},
focus
:
{
value
:
'
{colors.blue.400}
'
},
filled
:
{
value
:
{
_light
:
'
{colors.gray.300}
'
,
_dark
:
'
{colors.gray.600}
'
}
},
readOnly
:
{
value
:
{
_light
:
'
{colors.gray.200}
'
,
_dark
:
'
{colors.gray.800}
'
}
},
error
:
{
value
:
'
{colors.red.500}
'
},
},
},
field
:
{
placeholder
:
{
DEFAULT
:
{
value
:
'
{colors.gray.500}
'
},
disabled
:
{
value
:
'
{colors.gray.500/20}
'
},
error
:
{
value
:
'
{colors.red.500}
'
},
},
},
text
:
{
primary
:
{
value
:
{
_light
:
'
{colors.blackAlpha.800}
'
,
_dark
:
'
{colors.whiteAlpha.800}
'
}
},
secondary
:
{
value
:
{
_light
:
'
{colors.gray.500}
'
,
_dark
:
'
{colors.gray.400}
'
}
},
error
:
{
value
:
'
{colors.red.500}
'
},
},
border
:
{
divider
:
{
value
:
{
_light
:
'
{colors.blackAlpha.200}
'
,
_dark
:
'
{colors.whiteAlpha.200}
'
}
},
error
:
{
value
:
'
{colors.red.500}
'
},
},
global
:
{
body
:
{
...
...
toolkit/theme/recipes/field.recipe.ts
0 → 100644
View file @
30f65443
import
{
defineSlotRecipe
}
from
'
@chakra-ui/react
'
;
export
const
recipe
=
defineSlotRecipe
({
className
:
'
chakra-field
'
,
slots
:
[
'
root
'
,
'
label
'
,
'
requiredIndicator
'
,
'
errorText
'
,
'
helperText
'
],
base
:
{
requiredIndicator
:
{
color
:
'
inherit
'
,
lineHeight
:
'
inherit
'
,
},
root
:
{
display
:
'
flex
'
,
width
:
'
100%
'
,
position
:
'
relative
'
,
gap
:
'
1.5
'
,
},
label
:
{
display
:
'
flex
'
,
alignItems
:
'
center
'
,
textAlign
:
'
start
'
,
textStyle
:
'
sm
'
,
fontWeight
:
'
500
'
,
gap
:
'
0
'
,
userSelect
:
'
none
'
,
_disabled
:
{
opacity
:
'
0.5
'
,
},
_invalid
:
{
color
:
'
input.fg.error
'
,
},
},
errorText
:
{
display
:
'
inline-flex
'
,
alignItems
:
'
center
'
,
fontWeight
:
'
medium
'
,
gap
:
'
1
'
,
color
:
'
input.fg.error
'
,
textStyle
:
'
xs
'
,
},
helperText
:
{
color
:
'
fg.muted
'
,
textStyle
:
'
xs
'
,
},
},
variants
:
{
floating
:
{
'
true
'
:
{
label
:
{
pos
:
'
absolute
'
,
bg
:
'
bg
'
,
top
:
'
2px
'
,
left
:
'
2px
'
,
w
:
'
calc(100% - 4px)
'
,
borderRadius
:
'
base
'
,
pointerEvents
:
'
none
'
,
transformOrigin
:
'
top left
'
,
transitionProperty
:
'
font-size, line-height, padding, background-color
'
,
transitionDuration
:
'
fast
'
,
transitionTimingFunction
:
'
ease
'
,
},
},
},
size
:
{
sm
:
{
label
:
{
fontSize
:
'
sm
'
,
},
},
md
:
{
label
:
{
fontSize
:
'
md
'
,
},
},
lg
:
{
label
:
{
fontSize
:
'
md
'
,
},
},
xl
:
{
label
:
{
fontSize
:
'
md
'
,
},
},
},
orientation
:
{
vertical
:
{
root
:
{
flexDirection
:
'
column
'
,
alignItems
:
'
flex-start
'
,
},
},
horizontal
:
{
root
:
{
flexDirection
:
'
row
'
,
alignItems
:
'
center
'
,
justifyContent
:
'
space-between
'
,
},
label
:
{
flex
:
'
0 0 var(--field-label-width, 80px)
'
,
},
},
},
},
compoundVariants
:
[
{
size
:
'
xl
'
,
floating
:
true
,
css
:
{
label
:
{
padding
:
'
10px 16px 0px 16px
'
,
textStyle
:
'
xs
'
,
_peerPlaceholderShown
:
{
padding
:
'
16px
'
,
textStyle
:
'
md
'
,
},
_peerFocusVisible
:
{
padding
:
'
10px 16px 0px 16px
'
,
textStyle
:
'
xs
'
,
},
_readOnly
:
{
bg
:
'
input.bg.readOnly
'
,
},
},
errorText
:
{
fontSize
:
'
inherit
'
,
lineHeight
:
'
inherit
'
,
},
},
},
],
defaultVariants
:
{
floating
:
false
,
orientation
:
'
vertical
'
,
},
});
toolkit/theme/recipes/index.ts
View file @
30f65443
import
{
recipe
as
alert
}
from
'
./alert.recipe
'
;
import
{
recipe
as
button
}
from
'
./button.recipe
'
;
import
{
recipe
as
field
}
from
'
./field.recipe
'
;
import
{
recipe
as
input
}
from
'
./input.recipe
'
;
import
{
recipe
as
link
}
from
'
./link.recipe
'
;
import
{
recipe
as
popover
}
from
'
./popover.recipe
'
;
import
{
recipe
as
progressCircle
}
from
'
./progress-circle.recipe
'
;
...
...
@@ -11,12 +13,14 @@ import { recipe as tooltip } from './tooltip.recipe';
export
const
recipes
=
{
button
,
input
,
link
,
skeleton
,
};
export
const
slotRecipes
=
{
alert
,
field
,
popover
,
progressCircle
,
'
switch
'
:
switchRecipe
,
...
...
toolkit/theme/recipes/input.recipe.ts
0 → 100644
View file @
30f65443
import
{
defineRecipe
}
from
'
@chakra-ui/react
'
;
export
const
recipe
=
defineRecipe
({
base
:
{
width
:
'
100%
'
,
minWidth
:
'
0
'
,
outline
:
'
0
'
,
position
:
'
relative
'
,
appearance
:
'
none
'
,
textAlign
:
'
start
'
,
borderRadius
:
'
base
'
,
height
:
'
var(--input-height)
'
,
minW
:
'
var(--input-height)
'
,
color
:
'
input.fg
'
,
'
--focus-color
'
:
'
colors.border.error
'
,
'
--error-color
'
:
'
colors.border.error
'
,
_invalid
:
{
focusRingColor
:
'
var(--error-color)
'
,
borderColor
:
'
var(--error-color)
'
,
},
_autofill
:
{
// FIXME: this is not working
// WebkitTextFillColor: '{colors.input.fg}',
},
},
variants
:
{
size
:
{
sm
:
{
textStyle
:
'
sm
'
,
px
:
'
2
'
,
'
--input-height
'
:
'
sizes.8
'
,
},
md
:
{
textStyle
:
'
md
'
,
px
:
'
2
'
,
'
--input-height
'
:
'
sizes.10
'
,
},
lg
:
{
textStyle
:
'
md
'
,
px
:
'
3
'
,
'
--input-height
'
:
'
sizes.12
'
,
},
xl
:
{
textStyle
:
'
md
'
,
px
:
'
4
'
,
'
--input-height
'
:
'
60px
'
,
},
},
variant
:
{
outline
:
{
bg
:
'
input.bg
'
,
borderWidth
:
'
2px
'
,
borderColor
:
'
input.border
'
,
focusVisibleRing
:
'
none
'
,
_hover
:
{
borderColor
:
'
input.border.hover
'
,
},
_focus
:
{
borderColor
:
'
input.border.focus
'
,
_hover
:
{
borderColor
:
'
input.border.focus
'
,
},
},
_readOnly
:
{
userSelect
:
'
all
'
,
pointerEvents
:
'
none
'
,
bg
:
'
input.bg.readOnly
'
,
borderColor
:
'
input.border.readOnly
'
,
_focus
:
{
borderColor
:
'
input.border.readOnly
'
,
},
_hover
:
{
borderColor
:
'
input.border.readOnly
'
,
},
},
_disabled
:
{
bg
:
'
input.bg.disabled
'
,
borderColor
:
'
input.border.disabled
'
,
},
_invalid
:
{
borderColor
:
'
input.border.error
'
,
},
},
},
floating
:
{
'
true
'
:
{},
},
},
compoundVariants
:
[
{
size
:
'
xl
'
,
floating
:
true
,
css
:
{
padding
:
'
26px 10px 10px 16px
'
,
},
},
],
defaultVariants
:
{
size
:
'
md
'
,
variant
:
'
outline
'
,
floating
:
false
,
},
});
ui/pages/Chakra.tsx
View file @
30f65443
...
...
@@ -5,6 +5,8 @@ import React from 'react';
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
useColorMode
}
from
'
toolkit/chakra/color-mode
'
;
import
{
Field
}
from
'
toolkit/chakra/field
'
;
import
{
Input
}
from
'
toolkit/chakra/input
'
;
import
{
ProgressCircleRing
,
ProgressCircleRoot
}
from
'
toolkit/chakra/progress-circle
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Switch
}
from
'
toolkit/chakra/switch
'
;
...
...
@@ -37,6 +39,62 @@ const ChakraShowcases = () => {
</
HStack
>
</
section
>
<
section
>
<
Heading
textStyle=
"heading.md"
mb=
{
2
}
>
Inputs
</
Heading
>
<
Heading
textStyle=
"heading.sm"
mb=
{
2
}
>
Regular
</
Heading
>
<
HStack
gap=
{
4
}
whiteSpace=
"nowrap"
>
<
Field
label=
"Email"
required
>
<
Input
type=
"email"
/>
</
Field
>
<
Field
label=
"Email"
>
<
Input
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email"
invalid
>
<
Input
value=
"duck"
/>
</
Field
>
<
Field
label=
"Email"
readOnly
>
<
Input
value=
"duck"
/>
</
Field
>
<
Field
label=
"Email"
disabled
>
<
Input
value=
"duck"
/>
</
Field
>
</
HStack
>
<
HStack
gap=
{
4
}
whiteSpace=
"nowrap"
mt=
{
4
}
alignItems=
"flex-start"
>
<
Field
label=
"Email"
required
size=
"sm"
>
<
Input
/>
</
Field
>
<
Field
label=
"Email"
required
size=
"md"
>
<
Input
/>
</
Field
>
<
Field
label=
"Email"
required
size=
"lg"
>
<
Input
/>
</
Field
>
<
Field
label=
"Email"
required
size=
"xl"
>
<
Input
/>
</
Field
>
</
HStack
>
<
Heading
textStyle=
"heading.sm"
mb=
{
2
}
mt=
{
6
}
>
Floating (only XL size)
</
Heading
>
<
HStack
gap=
{
4
}
mt=
{
4
}
alignItems=
"flex-start"
>
<
Field
label=
"Email"
required
floating
size=
"xl"
w=
"300px"
>
<
Input
type=
"email"
/>
</
Field
>
<
Field
label=
"Email"
required
floating
invalid
errorText=
"Something went wrong"
size=
"xl"
w=
"300px"
>
<
Input
type=
"email"
/>
</
Field
>
</
HStack
>
<
HStack
p=
{
6
}
mt=
{
4
}
gap=
{
4
}
bgColor=
{
{
_light
:
'
blackAlpha.200
'
,
_dark
:
'
whiteAlpha.200
'
}
}
>
<
Field
label=
"Email"
required
floating
size=
"xl"
w=
"300px"
>
<
Input
type=
"email"
/>
</
Field
>
<
Field
label=
"Email"
required
floating
disabled
size=
"xl"
w=
"300px"
>
<
Input
type=
"email"
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email"
required
floating
readOnly
size=
"xl"
w=
"300px"
>
<
Input
type=
"email"
value=
"me@example.com"
/>
</
Field
>
</
HStack
>
</
section
>
<
section
>
<
Heading
textStyle=
"heading.md"
mb=
{
2
}
>
Links
</
Heading
>
<
HStack
gap=
{
4
}
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment