Layout scaffolding for Web apps.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

147 lines
3.5 KiB

  1. import tailwindPlugin from 'tailwindcss/plugin';
  2. export interface ViewfinderPluginOptions {
  3. baseWidth?: number;
  4. topbarHeight?: string;
  5. sizeMenu?: string;
  6. colorTopbar?: string;
  7. colorSidebar?: string;
  8. colorSidebarMenu?: string;
  9. }
  10. export const plugin = tailwindPlugin.withOptions<ViewfinderPluginOptions>(
  11. ({
  12. baseWidth = 360 as const,
  13. topbarHeight = '4rem' as const,
  14. sizeMenu = topbarHeight,
  15. colorTopbar = '255 255 255' as const,
  16. colorSidebarMenu = '255 255 255' as const,
  17. colorSidebar = '255 255 255' as const,
  18. } = {} as ViewfinderPluginOptions) => ({
  19. addBase,
  20. addComponents,
  21. addUtilities,
  22. }) => {
  23. addBase({
  24. ':root': {
  25. '--base-width': `${baseWidth}px`,
  26. '--height-topbar': topbarHeight,
  27. '--size-menu': sizeMenu,
  28. '--color-topbar': colorTopbar,
  29. '--color-sidebar': colorSidebar,
  30. '--color-sidebar-menu': colorSidebarMenu,
  31. },
  32. });
  33. addBase({
  34. ':root': {
  35. 'background-color': 'rgb(var(--color-background))',
  36. },
  37. });
  38. addComponents({
  39. '.topbar': {
  40. height: 'var(--height-topbar, 4rem)',
  41. '& ~ *': {
  42. 'padding-top': 'var(--height-topbar, 4rem)',
  43. },
  44. '& ~ [data-viewfinder="main"] ~ *': {
  45. 'padding-top': '0',
  46. },
  47. '& [data-viewfinder="menu"] > *': {
  48. 'width': '100%',
  49. 'height': '100%',
  50. 'display': 'grid',
  51. 'place-content': 'center',
  52. },
  53. '& [data-viewfinder="user"] > *': {
  54. 'width': '100%',
  55. 'height': '100%',
  56. 'display': 'grid',
  57. 'place-content': 'center',
  58. },
  59. [`@media (min-width: ${baseWidth * 3}px)`]: {
  60. '& ~ [data-viewfinder="main"] ~ *': {
  61. 'padding-top': 'var(--height-topbar, 4rem)',
  62. },
  63. '& [data-viewfinder="menu"] > *': {
  64. 'position': 'absolute',
  65. 'left': '-999999px',
  66. },
  67. '& [data-viewfinder="menu"] > *:focus': {
  68. 'position': 'static',
  69. },
  70. },
  71. },
  72. });
  73. addUtilities({
  74. '.scrollbar-hidden': {
  75. 'scrollbar-width': 'none',
  76. '&::-webkit-scrollbar': {
  77. 'display': 'none',
  78. },
  79. },
  80. });
  81. addComponents({
  82. '.left-sidebar-with-menu-base': {
  83. '& [data-viewfinder="menu-item"] > *': {
  84. 'height': '100%',
  85. 'display': 'flex',
  86. 'align-items': 'center',
  87. 'text-decoration': 'none',
  88. 'width': '100%',
  89. },
  90. [`@media (min-width: ${baseWidth * 3}px)`]: {
  91. '& [data-viewfinder="menu-item"]': {
  92. 'width': 'auto !important',
  93. },
  94. '& [data-viewfinder="menu-item"] > *': {
  95. 'height': 'auto',
  96. },
  97. },
  98. },
  99. });
  100. },
  101. ({
  102. baseWidth = 360 as const,
  103. } = {} as ViewfinderPluginOptions) => ({
  104. theme: {
  105. screens: {
  106. '3xs': `${baseWidth}px`,
  107. '2xs': `${baseWidth * 1.5}px`,
  108. xs: `${baseWidth * 2}px`,
  109. sm: `${baseWidth * 2.5}px`,
  110. md: `${baseWidth * 3}px`,
  111. lg: `${baseWidth * 4}px`,
  112. xl: `${baseWidth * 5}px`,
  113. '2xl': `${baseWidth * 6}px`,
  114. '3xl': `${baseWidth * 7}px`,
  115. },
  116. extend: {
  117. colors: {
  118. topbar: 'rgb(var(--color-topbar))',
  119. sidebar: 'rgb(var(--color-sidebar))',
  120. 'sidebar-menu': 'rgb(var(--color-sidebar-menu))',
  121. },
  122. spacing: {
  123. topbar: 'var(--height-topbar, 4rem)',
  124. menu: 'var(--size-menu, var(--height-topbar, 4rem))',
  125. inherit: 'inherit',
  126. },
  127. maxWidth: {
  128. 'screen-3xs': `${baseWidth}px`,
  129. 'screen-2xs': `${baseWidth * 1.5}px`,
  130. 'screen-xs': `${baseWidth * 2}px`,
  131. 'screen-sm': `${baseWidth * 2.5}px`,
  132. 'screen-md': `${baseWidth * 3}px`,
  133. 'screen-lg': `${baseWidth * 4}px`,
  134. 'screen-xl': `${baseWidth * 5}px`,
  135. 'screen-2xl': `${baseWidth * 6}px`,
  136. 'screen-3xl': `${baseWidth * 7}px`,
  137. },
  138. minWidth: {
  139. 32: '8rem',
  140. },
  141. },
  142. },
  143. }),
  144. );