diff --git a/ui-admin/upload/src/upload.component.tsx b/ui-admin/upload/src/component.tsx
similarity index 100%
rename from ui-admin/upload/src/upload.component.tsx
rename to ui-admin/upload/src/component.tsx
diff --git a/ui-admin/upload/src/container/container.css.ts b/ui-admin/upload/src/container/container.css.ts
index 49c4da688..440c621c0 100644
--- a/ui-admin/upload/src/container/container.css.ts
+++ b/ui-admin/upload/src/container/container.css.ts
@@ -4,8 +4,7 @@ import { vars } from '@atls-ui-admin/theme'
export const containerStyles = style({
position: 'relative',
- borderWidth: 2,
- borderStyle: 'dashed',
+ border: vars.borders.dashedGray,
cursor: 'pointer',
outline: 'none',
borderColor: vars.colors.black,
diff --git a/ui-admin/upload/src/dropzone-placeholder.component.tsx b/ui-admin/upload/src/dropzone-placeholder.component.tsx
deleted file mode 100644
index 124c40373..000000000
--- a/ui-admin/upload/src/dropzone-placeholder.component.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import type { ReactNode } from 'react'
-import type { PropsWithChildren } from 'react'
-
-import { UploadIcon } from '@atls-ui-admin/icons'
-
-import { PlaceholderAccept } from './placeholder-accept/index.js'
-import { PlaceholderIcon } from './placeholder-icon/index.js'
-import { PlaceholderLink } from './placeholder-link/index.js'
-import { dropzoneContainerStyles } from './container/container.css.js'
-
-export const DropzonePlaceholder = ({
- accept,
- children,
-}: PropsWithChildren<{ accept: ReactNode }>): ReactNode => (
-
-
-
-
-
{accept}
-
{children}
-
-)
diff --git a/ui-admin/upload/src/index.ts b/ui-admin/upload/src/index.ts
index 1e9daf294..4a2f39646 100644
--- a/ui-admin/upload/src/index.ts
+++ b/ui-admin/upload/src/index.ts
@@ -1,2 +1,2 @@
-export * from './upload.component.js'
-export * from './dropzone-placeholder.component.js'
+export * from './component.js'
+export * from './placeholder/dropzone/index.js'
diff --git a/ui-admin/upload/src/placeholder-accept/index.ts b/ui-admin/upload/src/placeholder-accept/index.ts
deleted file mode 100644
index 224fbd9f6..000000000
--- a/ui-admin/upload/src/placeholder-accept/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './placeholder-accept.component.js'
diff --git a/ui-admin/upload/src/placeholder-accept/placeholder-accept.component.tsx b/ui-admin/upload/src/placeholder-accept/placeholder-accept.component.tsx
deleted file mode 100644
index f3e290888..000000000
--- a/ui-admin/upload/src/placeholder-accept/placeholder-accept.component.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import type { ReactNode } from 'react'
-import type { HTMLAttributes } from 'react'
-
-import { clsx } from 'clsx'
-
-import { basePlaceholderAcceptStyles } from './placeholder-accept.css.js'
-
-export const PlaceholderAccept = ({
- children,
- className,
- ...props
-}: HTMLAttributes): ReactNode => (
-
- {children}
-
-)
diff --git a/ui-admin/upload/src/placeholder-icon/index.ts b/ui-admin/upload/src/placeholder-icon/index.ts
deleted file mode 100644
index 9c7fc0462..000000000
--- a/ui-admin/upload/src/placeholder-icon/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './placeholder-icon.component.js'
diff --git a/ui-admin/upload/src/placeholder-icon/placeholder-icon.component.tsx b/ui-admin/upload/src/placeholder-icon/placeholder-icon.component.tsx
deleted file mode 100644
index d99d041d8..000000000
--- a/ui-admin/upload/src/placeholder-icon/placeholder-icon.component.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import type { ReactNode } from 'react'
-import type { HTMLAttributes } from 'react'
-
-import { clsx } from 'clsx'
-
-import { basePlaceholderIconStyles } from './placeholder-icon.css.js'
-
-export const PlaceholderIcon = ({
- children,
- className,
- ...props
-}: HTMLAttributes): ReactNode => (
-
- {children}
-
-)
diff --git a/ui-admin/upload/src/placeholder-link/index.ts b/ui-admin/upload/src/placeholder-link/index.ts
deleted file mode 100644
index 797acb7a5..000000000
--- a/ui-admin/upload/src/placeholder-link/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './placeholder-link.component.js'
diff --git a/ui-admin/upload/src/placeholder/accept/component.tsx b/ui-admin/upload/src/placeholder/accept/component.tsx
new file mode 100644
index 000000000..66504938f
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/accept/component.tsx
@@ -0,0 +1,16 @@
+import type { ReactNode } from 'react'
+import type { HTMLAttributes } from 'react'
+
+import { clsx } from 'clsx'
+
+import { baseAcceptStyles } from './styles.css.js'
+
+export const PlaceholderAccept = ({
+ children,
+ className,
+ ...props
+}: HTMLAttributes): ReactNode => (
+
+ {children}
+
+)
diff --git a/ui-admin/upload/src/placeholder/accept/index.ts b/ui-admin/upload/src/placeholder/accept/index.ts
new file mode 100644
index 000000000..b7a151031
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/accept/index.ts
@@ -0,0 +1 @@
+export * from './component.js'
diff --git a/ui-admin/upload/src/placeholder-accept/placeholder-accept.css.ts b/ui-admin/upload/src/placeholder/accept/styles.css.ts
similarity index 81%
rename from ui-admin/upload/src/placeholder-accept/placeholder-accept.css.ts
rename to ui-admin/upload/src/placeholder/accept/styles.css.ts
index 76d46e2bd..4183eae86 100644
--- a/ui-admin/upload/src/placeholder-accept/placeholder-accept.css.ts
+++ b/ui-admin/upload/src/placeholder/accept/styles.css.ts
@@ -2,7 +2,7 @@ import { style } from '@vanilla-extract/css'
import { vars } from '@atls-ui-admin/theme'
-export const basePlaceholderAcceptStyles = style({
+export const baseAcceptStyles = style({
padding: `${vars.space.g8} ${vars.space.zero}`,
color: vars.colors['icons.placeholder'],
fontFamily: vars.fonts.primary,
diff --git a/ui-admin/upload/src/placeholder/placeholder.component.tsx b/ui-admin/upload/src/placeholder/component.tsx
similarity index 85%
rename from ui-admin/upload/src/placeholder/placeholder.component.tsx
rename to ui-admin/upload/src/placeholder/component.tsx
index 2207278af..9a65ced66 100644
--- a/ui-admin/upload/src/placeholder/placeholder.component.tsx
+++ b/ui-admin/upload/src/placeholder/component.tsx
@@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'react'
import { clsx } from 'clsx'
-import { basePlaceholderStyles } from './placeholder.css.js'
+import { basePlaceholderStyles } from './styles.css.js'
export const Placeholder = ({
children,
diff --git a/ui-admin/upload/src/placeholder/dropzone/component.tsx b/ui-admin/upload/src/placeholder/dropzone/component.tsx
new file mode 100644
index 000000000..8355c3cb6
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/dropzone/component.tsx
@@ -0,0 +1,29 @@
+import type { ReactNode } from 'react'
+import type { PropsWithChildren } from 'react'
+
+import type { DropzonePlaceholderProps } from './interfaces.js'
+
+import { clsx } from 'clsx'
+
+import { UploadIcon } from '@atls-ui-admin/icons'
+
+import { PlaceholderAccept } from '../accept/index.js'
+import { PlaceholderIcon } from '../icon/index.js'
+import { PlaceholderLink } from '../link/index.js'
+import { dropzoneContainerStyles } from '../../container/container.css.js'
+
+export const DropzonePlaceholder = ({
+ accept,
+ children,
+ className,
+ slotProps,
+ ...props
+}: PropsWithChildren): ReactNode => (
+
+
+
+
+
{accept}
+
{children}
+
+)
diff --git a/ui-admin/upload/src/placeholder/dropzone/index.ts b/ui-admin/upload/src/placeholder/dropzone/index.ts
new file mode 100644
index 000000000..049e831d6
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/dropzone/index.ts
@@ -0,0 +1,2 @@
+export type * from './interfaces.js'
+export * from './component.js'
diff --git a/ui-admin/upload/src/placeholder/dropzone/interfaces.ts b/ui-admin/upload/src/placeholder/dropzone/interfaces.ts
new file mode 100644
index 000000000..8e7d6f11d
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/dropzone/interfaces.ts
@@ -0,0 +1,14 @@
+import type { AnchorHTMLAttributes } from 'react'
+import type { HTMLAttributes } from 'react'
+import type { ReactNode } from 'react'
+
+export interface DropzonePlaceholderSlotProps {
+ icon?: HTMLAttributes
+ accept?: HTMLAttributes
+ link?: AnchorHTMLAttributes
+}
+
+export interface DropzonePlaceholderProps extends HTMLAttributes {
+ accept: ReactNode
+ slotProps?: DropzonePlaceholderSlotProps
+}
diff --git a/ui-admin/upload/src/placeholder/icon/component.tsx b/ui-admin/upload/src/placeholder/icon/component.tsx
new file mode 100644
index 000000000..a28ab808c
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/icon/component.tsx
@@ -0,0 +1,16 @@
+import type { ReactNode } from 'react'
+import type { HTMLAttributes } from 'react'
+
+import { clsx } from 'clsx'
+
+import { baseIconStyles } from './styles.css.js'
+
+export const PlaceholderIcon = ({
+ children,
+ className,
+ ...props
+}: HTMLAttributes): ReactNode => (
+
+ {children}
+
+)
diff --git a/ui-admin/upload/src/placeholder/icon/index.ts b/ui-admin/upload/src/placeholder/icon/index.ts
new file mode 100644
index 000000000..b7a151031
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/icon/index.ts
@@ -0,0 +1 @@
+export * from './component.js'
diff --git a/ui-admin/upload/src/placeholder-icon/placeholder-icon.css.ts b/ui-admin/upload/src/placeholder/icon/styles.css.ts
similarity index 82%
rename from ui-admin/upload/src/placeholder-icon/placeholder-icon.css.ts
rename to ui-admin/upload/src/placeholder/icon/styles.css.ts
index bec72dabf..788f4e3a0 100644
--- a/ui-admin/upload/src/placeholder-icon/placeholder-icon.css.ts
+++ b/ui-admin/upload/src/placeholder/icon/styles.css.ts
@@ -2,7 +2,7 @@ import { style } from '@vanilla-extract/css'
import { vars } from '@atls-ui-admin/theme'
-export const basePlaceholderIconStyles = style({
+export const baseIconStyles = style({
padding: `${vars.space.g4} ${vars.space.zero}`,
color: vars.colors['icons.placeholder'],
fill: vars.colors['icons.placeholder'],
diff --git a/ui-admin/upload/src/placeholder/index.ts b/ui-admin/upload/src/placeholder/index.ts
index 03f0e691e..3f3d04e09 100644
--- a/ui-admin/upload/src/placeholder/index.ts
+++ b/ui-admin/upload/src/placeholder/index.ts
@@ -1 +1,2 @@
-export * from './placeholder.component.js'
+export * from './component.js'
+export * from './dropzone/index.js'
diff --git a/ui-admin/upload/src/placeholder-link/placeholder-link.component.tsx b/ui-admin/upload/src/placeholder/link/component.tsx
similarity index 68%
rename from ui-admin/upload/src/placeholder-link/placeholder-link.component.tsx
rename to ui-admin/upload/src/placeholder/link/component.tsx
index 6c401091b..1e69470b6 100644
--- a/ui-admin/upload/src/placeholder-link/placeholder-link.component.tsx
+++ b/ui-admin/upload/src/placeholder/link/component.tsx
@@ -3,14 +3,14 @@ import type { AnchorHTMLAttributes } from 'react'
import { clsx } from 'clsx'
-import { basePlaceholderLinkStyles } from './placeholder-link.css.js'
+import { baseLinkStyles } from './styles.css.js'
export const PlaceholderLink = ({
children,
className,
...props
}: AnchorHTMLAttributes): ReactNode => (
-
+
{children}
)
diff --git a/ui-admin/upload/src/placeholder/link/index.ts b/ui-admin/upload/src/placeholder/link/index.ts
new file mode 100644
index 000000000..b7a151031
--- /dev/null
+++ b/ui-admin/upload/src/placeholder/link/index.ts
@@ -0,0 +1 @@
+export * from './component.js'
diff --git a/ui-admin/upload/src/placeholder-link/placeholder-link.css.ts b/ui-admin/upload/src/placeholder/link/styles.css.ts
similarity index 85%
rename from ui-admin/upload/src/placeholder-link/placeholder-link.css.ts
rename to ui-admin/upload/src/placeholder/link/styles.css.ts
index 7ce6ab94e..0a5525d5b 100644
--- a/ui-admin/upload/src/placeholder-link/placeholder-link.css.ts
+++ b/ui-admin/upload/src/placeholder/link/styles.css.ts
@@ -2,7 +2,7 @@ import { style } from '@vanilla-extract/css'
import { vars } from '@atls-ui-admin/theme'
-export const basePlaceholderLinkStyles = style({
+export const baseLinkStyles = style({
padding: `${vars.space.g8} ${vars.space.zero}`,
// @ts-expect-error correct text.blue field
color: vars.colors['text.blue'],
diff --git a/ui-admin/upload/src/placeholder/placeholder.css.ts b/ui-admin/upload/src/placeholder/styles.css.ts
similarity index 100%
rename from ui-admin/upload/src/placeholder/placeholder.css.ts
rename to ui-admin/upload/src/placeholder/styles.css.ts
diff --git a/ui-admin/upload/src/upload.stories.tsx b/ui-admin/upload/src/upload.stories.tsx
deleted file mode 100644
index 416d12f2b..000000000
--- a/ui-admin/upload/src/upload.stories.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import type { ButtonProps } from '@atls-ui-admin/button'
-import type { Meta } from '@storybook/react'
-import type { StoryObj } from '@storybook/react'
-import type { ReactNode } from 'react'
-
-import { useTheme } from 'next-themes'
-
-import { Button } from '@atls-ui-admin/button'
-import { ThemeProvider } from '@atls-ui-admin/theme'
-import { buttonAppearances } from '@atls-ui-admin/button'
-import { buttonShapes } from '@atls-ui-admin/button'
-
-import { DropzonePlaceholder } from './index.js'
-import { Upload } from './index.js'
-
-type ButtonAppearanceName = keyof typeof buttonAppearances
-type ButtonShapeName = keyof typeof buttonShapes
-
-interface UploadStoryProps {
- appearance: ButtonAppearanceName
- shape: ButtonShapeName
-}
-
-const ToggleTheme = (props: ButtonProps): ReactNode => {
- const { theme, setTheme } = useTheme()
-
- return (
-
- )
-}
-
-const meta: Meta = {
- title: 'Admin/Upload',
- render: ({ appearance, shape }) => (
-
-
-
- Нажмите, чтобы загрузить
-
- }
- >
-
-
-
- ),
- tags: ['autodocs'],
- argTypes: {
- appearance: {
- control: { type: 'inline-radio' },
- options: Object.keys(buttonAppearances),
- },
- shape: {
- control: { type: 'select' },
- options: Object.keys(buttonShapes),
- },
- },
-}
-
-export default meta
-
-type Story = StoryObj
-
-export const BaseUpload: Story = {
- name: 'Базовый',
- args: {
- appearance: 'blue',
- shape: 'huge',
- },
-}
diff --git a/ui-admin/upload/stories/interfaces.ts b/ui-admin/upload/stories/interfaces.ts
new file mode 100644
index 000000000..6a04fb053
--- /dev/null
+++ b/ui-admin/upload/stories/interfaces.ts
@@ -0,0 +1,11 @@
+import type { buttonAppearances } from '@atls-ui-admin/button'
+import type { buttonShapes } from '@atls-ui-admin/button'
+
+export type ButtonAppearanceName = keyof typeof buttonAppearances
+export type ButtonShapeName = keyof typeof buttonShapes
+
+export interface UploadStoryProps {
+ appearance: ButtonAppearanceName
+ customPlaceholder: boolean
+ shape: ButtonShapeName
+}
diff --git a/ui-admin/upload/stories/styles.css.ts b/ui-admin/upload/stories/styles.css.ts
new file mode 100644
index 000000000..b10cedf3c
--- /dev/null
+++ b/ui-admin/upload/stories/styles.css.ts
@@ -0,0 +1,45 @@
+import { style } from '@vanilla-extract/css'
+
+import { vars } from '@atls-ui-admin/theme'
+
+export const customPlaceholderRootStyles = style({
+ gap: vars.space.g4,
+ padding: `${vars.space.g16} ${vars.space.g24}`,
+ borderRadius: vars.radii.f8,
+ backgroundColor: vars.colors.blueProtective,
+})
+
+export const customPlaceholderIconStyles = style({
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ width: 64,
+ height: 64,
+ borderRadius: vars.radii.full,
+ color: vars.colors.blue,
+ fill: vars.colors.blue,
+ backgroundColor: vars.colors.white,
+})
+
+export const customPlaceholderAcceptStyles = style({
+ padding: vars.space.zero,
+ color: vars.colors.black,
+ fontWeight: vars.fontWeights.bold,
+})
+
+export const customPlaceholderLinkStyles = style({
+ padding: vars.space.zero,
+ color: vars.colors.blue,
+ fontWeight: vars.fontWeights.bold,
+ textDecoration: 'none',
+})
+
+export const toggleThemeStyles = style({
+ width: 'fit-content',
+ margin: `${vars.space.zero} ${vars.space.zero} ${vars.space.g10} auto`,
+})
+
+export const uploadAreaStyles = style({
+ width: '100%',
+ height: 200,
+})
diff --git a/ui-admin/upload/stories/upload.stories.tsx b/ui-admin/upload/stories/upload.stories.tsx
new file mode 100644
index 000000000..2e2e82ba1
--- /dev/null
+++ b/ui-admin/upload/stories/upload.stories.tsx
@@ -0,0 +1,96 @@
+import type { ButtonProps } from '@atls-ui-admin/button'
+import type { Meta } from '@storybook/react'
+import type { StoryObj } from '@storybook/react'
+import type { ReactElement } from 'react'
+import type { ReactNode } from 'react'
+
+import type { UploadStoryProps } from './interfaces.js'
+
+import { useTheme } from 'next-themes'
+
+import { Button } from '@atls-ui-admin/button'
+import { ThemeProvider } from '@atls-ui-admin/theme'
+import { buttonAppearances } from '@atls-ui-admin/button'
+import { buttonShapes } from '@atls-ui-admin/button'
+
+import { DropzonePlaceholder } from '../src/index.js'
+import { Upload } from '../src/index.js'
+import { customPlaceholderAcceptStyles } from './styles.css.js'
+import { customPlaceholderIconStyles } from './styles.css.js'
+import { customPlaceholderLinkStyles } from './styles.css.js'
+import { customPlaceholderRootStyles } from './styles.css.js'
+import { toggleThemeStyles } from './styles.css.js'
+import { uploadAreaStyles } from './styles.css.js'
+
+const ToggleTheme = (props: ButtonProps): ReactElement => {
+ const { theme, setTheme } = useTheme()
+
+ return (
+
+ )
+}
+
+const renderPlaceholder = (customPlaceholder: boolean): ReactNode => (
+
+ Нажмите, чтобы загрузить
+
+)
+
+const meta: Meta = {
+ title: 'Admin/Upload',
+ render: ({ appearance, customPlaceholder, shape }): ReactElement => (
+
+
+
+
+
+
+ ),
+ tags: ['autodocs'],
+ argTypes: {
+ appearance: {
+ control: { type: 'inline-radio' },
+ options: Object.keys(buttonAppearances),
+ },
+ customPlaceholder: {
+ control: { type: 'boolean' },
+ },
+ shape: {
+ control: { type: 'select' },
+ options: Object.keys(buttonShapes),
+ },
+ },
+}
+
+export default meta
+
+type Story = StoryObj
+
+export const BaseUpload: Story = {
+ name: 'Базовый',
+ args: {
+ appearance: 'blue',
+ customPlaceholder: false,
+ shape: 'huge',
+ },
+}