mirror of
https://github.com/BradNut/AdelieStack
synced 2025-09-08 17:40:20 +00:00
Updating to TofuStack formatting of APIs with old version for starting the hono service. Getting scaffolding for signup with username/email set up.
This commit is contained in:
parent
2c2f33ea68
commit
64f0e10715
410 changed files with 11048 additions and 10240 deletions
549
.editorconfig
Normal file
549
.editorconfig
Normal file
|
|
@ -0,0 +1,549 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = tab
|
||||
insert_final_newline = false
|
||||
max_line_length = 120
|
||||
tab_width = 2
|
||||
ij_continuation_indent_size = 4
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = false
|
||||
ij_smart_tabs = false
|
||||
ij_visual_guides = none
|
||||
ij_wrap_on_typing = false
|
||||
|
||||
[*.css]
|
||||
ij_css_align_closing_brace_with_properties = false
|
||||
ij_css_blank_lines_around_nested_selector = 1
|
||||
ij_css_blank_lines_between_blocks = 1
|
||||
ij_css_block_comment_add_space = false
|
||||
ij_css_brace_placement = end_of_line
|
||||
ij_css_enforce_quotes_on_format = false
|
||||
ij_css_hex_color_long_format = false
|
||||
ij_css_hex_color_lower_case = false
|
||||
ij_css_hex_color_short_format = false
|
||||
ij_css_hex_color_upper_case = false
|
||||
ij_css_keep_blank_lines_in_code = 2
|
||||
ij_css_keep_indents_on_empty_lines = false
|
||||
ij_css_keep_single_line_blocks = false
|
||||
ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||
ij_css_space_after_colon = true
|
||||
ij_css_space_before_opening_brace = true
|
||||
ij_css_use_double_quotes = true
|
||||
ij_css_value_alignment = do_not_align
|
||||
|
||||
[*.less]
|
||||
ij_less_align_closing_brace_with_properties = false
|
||||
ij_less_blank_lines_around_nested_selector = 1
|
||||
ij_less_blank_lines_between_blocks = 1
|
||||
ij_less_block_comment_add_space = false
|
||||
ij_less_brace_placement = 0
|
||||
ij_less_enforce_quotes_on_format = false
|
||||
ij_less_hex_color_long_format = false
|
||||
ij_less_hex_color_lower_case = false
|
||||
ij_less_hex_color_short_format = false
|
||||
ij_less_hex_color_upper_case = false
|
||||
ij_less_keep_blank_lines_in_code = 2
|
||||
ij_less_keep_indents_on_empty_lines = false
|
||||
ij_less_keep_single_line_blocks = false
|
||||
ij_less_line_comment_add_space = false
|
||||
ij_less_line_comment_at_first_column = false
|
||||
ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||
ij_less_space_after_colon = true
|
||||
ij_less_space_before_opening_brace = true
|
||||
ij_less_use_double_quotes = true
|
||||
ij_less_value_alignment = 0
|
||||
|
||||
[*.sass]
|
||||
ij_sass_align_closing_brace_with_properties = false
|
||||
ij_sass_blank_lines_around_nested_selector = 1
|
||||
ij_sass_blank_lines_between_blocks = 1
|
||||
ij_sass_brace_placement = 0
|
||||
ij_sass_enforce_quotes_on_format = false
|
||||
ij_sass_hex_color_long_format = false
|
||||
ij_sass_hex_color_lower_case = false
|
||||
ij_sass_hex_color_short_format = false
|
||||
ij_sass_hex_color_upper_case = false
|
||||
ij_sass_keep_blank_lines_in_code = 2
|
||||
ij_sass_keep_indents_on_empty_lines = false
|
||||
ij_sass_keep_single_line_blocks = false
|
||||
ij_sass_line_comment_add_space = false
|
||||
ij_sass_line_comment_at_first_column = false
|
||||
ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||
ij_sass_space_after_colon = true
|
||||
ij_sass_space_before_opening_brace = true
|
||||
ij_sass_use_double_quotes = true
|
||||
ij_sass_value_alignment = 0
|
||||
|
||||
[*.scss]
|
||||
ij_scss_align_closing_brace_with_properties = false
|
||||
ij_scss_blank_lines_around_nested_selector = 1
|
||||
ij_scss_blank_lines_between_blocks = 1
|
||||
ij_scss_block_comment_add_space = false
|
||||
ij_scss_brace_placement = 0
|
||||
ij_scss_enforce_quotes_on_format = false
|
||||
ij_scss_hex_color_long_format = false
|
||||
ij_scss_hex_color_lower_case = false
|
||||
ij_scss_hex_color_short_format = false
|
||||
ij_scss_hex_color_upper_case = false
|
||||
ij_scss_keep_blank_lines_in_code = 2
|
||||
ij_scss_keep_indents_on_empty_lines = false
|
||||
ij_scss_keep_single_line_blocks = false
|
||||
ij_scss_line_comment_add_space = false
|
||||
ij_scss_line_comment_at_first_column = false
|
||||
ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
|
||||
ij_scss_space_after_colon = true
|
||||
ij_scss_space_before_opening_brace = true
|
||||
ij_scss_use_double_quotes = true
|
||||
ij_scss_value_alignment = 0
|
||||
|
||||
[.editorconfig]
|
||||
ij_editorconfig_align_group_field_declarations = false
|
||||
ij_editorconfig_space_after_colon = false
|
||||
ij_editorconfig_space_after_comma = true
|
||||
ij_editorconfig_space_before_colon = false
|
||||
ij_editorconfig_space_before_comma = false
|
||||
ij_editorconfig_spaces_around_assignment_operators = true
|
||||
|
||||
[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
|
||||
ij_xml_align_attributes = true
|
||||
ij_xml_align_text = false
|
||||
ij_xml_attribute_wrap = normal
|
||||
ij_xml_block_comment_add_space = false
|
||||
ij_xml_block_comment_at_first_column = true
|
||||
ij_xml_keep_blank_lines = 2
|
||||
ij_xml_keep_indents_on_empty_lines = false
|
||||
ij_xml_keep_line_breaks = true
|
||||
ij_xml_keep_line_breaks_in_text = true
|
||||
ij_xml_keep_whitespaces = false
|
||||
ij_xml_keep_whitespaces_around_cdata = preserve
|
||||
ij_xml_keep_whitespaces_inside_cdata = false
|
||||
ij_xml_line_comment_at_first_column = true
|
||||
ij_xml_space_after_tag_name = false
|
||||
ij_xml_space_around_equals_in_attribute = false
|
||||
ij_xml_space_inside_empty_tag = false
|
||||
ij_xml_text_wrap = normal
|
||||
ij_xml_use_custom_settings = false
|
||||
|
||||
[{*.ats,*.cts,*.mts,*.ts}]
|
||||
ij_typescript_align_imports = false
|
||||
ij_typescript_align_multiline_array_initializer_expression = false
|
||||
ij_typescript_align_multiline_binary_operation = false
|
||||
ij_typescript_align_multiline_chained_methods = false
|
||||
ij_typescript_align_multiline_extends_list = false
|
||||
ij_typescript_align_multiline_for = true
|
||||
ij_typescript_align_multiline_parameters = true
|
||||
ij_typescript_align_multiline_parameters_in_calls = false
|
||||
ij_typescript_align_multiline_ternary_operation = false
|
||||
ij_typescript_align_object_properties = 0
|
||||
ij_typescript_align_union_types = false
|
||||
ij_typescript_align_var_statements = 0
|
||||
ij_typescript_array_initializer_new_line_after_left_brace = false
|
||||
ij_typescript_array_initializer_right_brace_on_new_line = false
|
||||
ij_typescript_array_initializer_wrap = off
|
||||
ij_typescript_assignment_wrap = off
|
||||
ij_typescript_binary_operation_sign_on_next_line = false
|
||||
ij_typescript_binary_operation_wrap = off
|
||||
ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
|
||||
ij_typescript_blank_lines_after_imports = 1
|
||||
ij_typescript_blank_lines_around_class = 1
|
||||
ij_typescript_blank_lines_around_field = 0
|
||||
ij_typescript_blank_lines_around_field_in_interface = 0
|
||||
ij_typescript_blank_lines_around_function = 1
|
||||
ij_typescript_blank_lines_around_method = 1
|
||||
ij_typescript_blank_lines_around_method_in_interface = 1
|
||||
ij_typescript_block_brace_style = end_of_line
|
||||
ij_typescript_block_comment_add_space = false
|
||||
ij_typescript_block_comment_at_first_column = true
|
||||
ij_typescript_call_parameters_new_line_after_left_paren = false
|
||||
ij_typescript_call_parameters_right_paren_on_new_line = false
|
||||
ij_typescript_call_parameters_wrap = off
|
||||
ij_typescript_catch_on_new_line = false
|
||||
ij_typescript_chained_call_dot_on_new_line = true
|
||||
ij_typescript_class_brace_style = end_of_line
|
||||
ij_typescript_comma_on_new_line = false
|
||||
ij_typescript_do_while_brace_force = never
|
||||
ij_typescript_else_on_new_line = false
|
||||
ij_typescript_enforce_trailing_comma = keep
|
||||
ij_typescript_enum_constants_wrap = on_every_item
|
||||
ij_typescript_extends_keyword_wrap = off
|
||||
ij_typescript_extends_list_wrap = off
|
||||
ij_typescript_field_prefix = _
|
||||
ij_typescript_file_name_style = relaxed
|
||||
ij_typescript_finally_on_new_line = false
|
||||
ij_typescript_for_brace_force = never
|
||||
ij_typescript_for_statement_new_line_after_left_paren = false
|
||||
ij_typescript_for_statement_right_paren_on_new_line = false
|
||||
ij_typescript_for_statement_wrap = off
|
||||
ij_typescript_force_quote_style = false
|
||||
ij_typescript_force_semicolon_style = false
|
||||
ij_typescript_function_expression_brace_style = end_of_line
|
||||
ij_typescript_if_brace_force = never
|
||||
ij_typescript_import_merge_members = global
|
||||
ij_typescript_import_prefer_absolute_path = global
|
||||
ij_typescript_import_sort_members = true
|
||||
ij_typescript_import_sort_module_name = false
|
||||
ij_typescript_import_use_node_resolution = true
|
||||
ij_typescript_imports_wrap = on_every_item
|
||||
ij_typescript_indent_case_from_switch = true
|
||||
ij_typescript_indent_chained_calls = true
|
||||
ij_typescript_indent_package_children = 0
|
||||
ij_typescript_jsdoc_include_types = false
|
||||
ij_typescript_jsx_attribute_value = braces
|
||||
ij_typescript_keep_blank_lines_in_code = 2
|
||||
ij_typescript_keep_first_column_comment = true
|
||||
ij_typescript_keep_indents_on_empty_lines = false
|
||||
ij_typescript_keep_line_breaks = true
|
||||
ij_typescript_keep_simple_blocks_in_one_line = false
|
||||
ij_typescript_keep_simple_methods_in_one_line = false
|
||||
ij_typescript_line_comment_add_space = true
|
||||
ij_typescript_line_comment_at_first_column = false
|
||||
ij_typescript_method_brace_style = end_of_line
|
||||
ij_typescript_method_call_chain_wrap = off
|
||||
ij_typescript_method_parameters_new_line_after_left_paren = false
|
||||
ij_typescript_method_parameters_right_paren_on_new_line = false
|
||||
ij_typescript_method_parameters_wrap = off
|
||||
ij_typescript_object_literal_wrap = on_every_item
|
||||
ij_typescript_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_typescript_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_typescript_place_assignment_sign_on_next_line = false
|
||||
ij_typescript_prefer_as_type_cast = false
|
||||
ij_typescript_prefer_explicit_types_function_expression_returns = false
|
||||
ij_typescript_prefer_explicit_types_function_returns = false
|
||||
ij_typescript_prefer_explicit_types_vars_fields = false
|
||||
ij_typescript_prefer_parameters_wrap = false
|
||||
ij_typescript_reformat_c_style_comments = false
|
||||
ij_typescript_space_after_colon = true
|
||||
ij_typescript_space_after_comma = true
|
||||
ij_typescript_space_after_dots_in_rest_parameter = false
|
||||
ij_typescript_space_after_generator_mult = true
|
||||
ij_typescript_space_after_property_colon = true
|
||||
ij_typescript_space_after_quest = true
|
||||
ij_typescript_space_after_type_colon = true
|
||||
ij_typescript_space_after_unary_not = false
|
||||
ij_typescript_space_before_async_arrow_lparen = true
|
||||
ij_typescript_space_before_catch_keyword = true
|
||||
ij_typescript_space_before_catch_left_brace = true
|
||||
ij_typescript_space_before_catch_parentheses = true
|
||||
ij_typescript_space_before_class_lbrace = true
|
||||
ij_typescript_space_before_class_left_brace = true
|
||||
ij_typescript_space_before_colon = true
|
||||
ij_typescript_space_before_comma = false
|
||||
ij_typescript_space_before_do_left_brace = true
|
||||
ij_typescript_space_before_else_keyword = true
|
||||
ij_typescript_space_before_else_left_brace = true
|
||||
ij_typescript_space_before_finally_keyword = true
|
||||
ij_typescript_space_before_finally_left_brace = true
|
||||
ij_typescript_space_before_for_left_brace = true
|
||||
ij_typescript_space_before_for_parentheses = true
|
||||
ij_typescript_space_before_for_semicolon = false
|
||||
ij_typescript_space_before_function_left_parenth = true
|
||||
ij_typescript_space_before_generator_mult = false
|
||||
ij_typescript_space_before_if_left_brace = true
|
||||
ij_typescript_space_before_if_parentheses = true
|
||||
ij_typescript_space_before_method_call_parentheses = false
|
||||
ij_typescript_space_before_method_left_brace = true
|
||||
ij_typescript_space_before_method_parentheses = false
|
||||
ij_typescript_space_before_property_colon = false
|
||||
ij_typescript_space_before_quest = true
|
||||
ij_typescript_space_before_switch_left_brace = true
|
||||
ij_typescript_space_before_switch_parentheses = true
|
||||
ij_typescript_space_before_try_left_brace = true
|
||||
ij_typescript_space_before_type_colon = false
|
||||
ij_typescript_space_before_unary_not = false
|
||||
ij_typescript_space_before_while_keyword = true
|
||||
ij_typescript_space_before_while_left_brace = true
|
||||
ij_typescript_space_before_while_parentheses = true
|
||||
ij_typescript_spaces_around_additive_operators = true
|
||||
ij_typescript_spaces_around_arrow_function_operator = true
|
||||
ij_typescript_spaces_around_assignment_operators = true
|
||||
ij_typescript_spaces_around_bitwise_operators = true
|
||||
ij_typescript_spaces_around_equality_operators = true
|
||||
ij_typescript_spaces_around_logical_operators = true
|
||||
ij_typescript_spaces_around_multiplicative_operators = true
|
||||
ij_typescript_spaces_around_relational_operators = true
|
||||
ij_typescript_spaces_around_shift_operators = true
|
||||
ij_typescript_spaces_around_unary_operator = false
|
||||
ij_typescript_spaces_within_array_initializer_brackets = false
|
||||
ij_typescript_spaces_within_brackets = false
|
||||
ij_typescript_spaces_within_catch_parentheses = false
|
||||
ij_typescript_spaces_within_for_parentheses = false
|
||||
ij_typescript_spaces_within_if_parentheses = false
|
||||
ij_typescript_spaces_within_imports = false
|
||||
ij_typescript_spaces_within_interpolation_expressions = false
|
||||
ij_typescript_spaces_within_method_call_parentheses = false
|
||||
ij_typescript_spaces_within_method_parentheses = false
|
||||
ij_typescript_spaces_within_object_literal_braces = false
|
||||
ij_typescript_spaces_within_object_type_braces = true
|
||||
ij_typescript_spaces_within_parentheses = false
|
||||
ij_typescript_spaces_within_switch_parentheses = false
|
||||
ij_typescript_spaces_within_type_assertion = false
|
||||
ij_typescript_spaces_within_union_types = true
|
||||
ij_typescript_spaces_within_while_parentheses = false
|
||||
ij_typescript_special_else_if_treatment = true
|
||||
ij_typescript_ternary_operation_signs_on_next_line = false
|
||||
ij_typescript_ternary_operation_wrap = off
|
||||
ij_typescript_union_types_wrap = on_every_item
|
||||
ij_typescript_use_chained_calls_group_indents = false
|
||||
ij_typescript_use_double_quotes = true
|
||||
ij_typescript_use_explicit_js_extension = auto
|
||||
ij_typescript_use_path_mapping = always
|
||||
ij_typescript_use_public_modifier = false
|
||||
ij_typescript_use_semicolon_after_statement = true
|
||||
ij_typescript_var_declaration_wrap = normal
|
||||
ij_typescript_while_brace_force = never
|
||||
ij_typescript_while_on_new_line = false
|
||||
ij_typescript_wrap_comments = false
|
||||
|
||||
[{*.cjs,*.js}]
|
||||
ij_javascript_align_imports = false
|
||||
ij_javascript_align_multiline_array_initializer_expression = false
|
||||
ij_javascript_align_multiline_binary_operation = false
|
||||
ij_javascript_align_multiline_chained_methods = false
|
||||
ij_javascript_align_multiline_extends_list = false
|
||||
ij_javascript_align_multiline_for = true
|
||||
ij_javascript_align_multiline_parameters = true
|
||||
ij_javascript_align_multiline_parameters_in_calls = false
|
||||
ij_javascript_align_multiline_ternary_operation = false
|
||||
ij_javascript_align_object_properties = 0
|
||||
ij_javascript_align_union_types = false
|
||||
ij_javascript_align_var_statements = 0
|
||||
ij_javascript_array_initializer_new_line_after_left_brace = false
|
||||
ij_javascript_array_initializer_right_brace_on_new_line = false
|
||||
ij_javascript_array_initializer_wrap = off
|
||||
ij_javascript_assignment_wrap = off
|
||||
ij_javascript_binary_operation_sign_on_next_line = false
|
||||
ij_javascript_binary_operation_wrap = off
|
||||
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
|
||||
ij_javascript_blank_lines_after_imports = 1
|
||||
ij_javascript_blank_lines_around_class = 1
|
||||
ij_javascript_blank_lines_around_field = 0
|
||||
ij_javascript_blank_lines_around_function = 1
|
||||
ij_javascript_blank_lines_around_method = 1
|
||||
ij_javascript_block_brace_style = end_of_line
|
||||
ij_javascript_block_comment_add_space = false
|
||||
ij_javascript_block_comment_at_first_column = true
|
||||
ij_javascript_call_parameters_new_line_after_left_paren = false
|
||||
ij_javascript_call_parameters_right_paren_on_new_line = false
|
||||
ij_javascript_call_parameters_wrap = off
|
||||
ij_javascript_catch_on_new_line = false
|
||||
ij_javascript_chained_call_dot_on_new_line = true
|
||||
ij_javascript_class_brace_style = end_of_line
|
||||
ij_javascript_comma_on_new_line = false
|
||||
ij_javascript_do_while_brace_force = never
|
||||
ij_javascript_else_on_new_line = false
|
||||
ij_javascript_enforce_trailing_comma = keep
|
||||
ij_javascript_extends_keyword_wrap = off
|
||||
ij_javascript_extends_list_wrap = off
|
||||
ij_javascript_field_prefix = _
|
||||
ij_javascript_file_name_style = relaxed
|
||||
ij_javascript_finally_on_new_line = false
|
||||
ij_javascript_for_brace_force = never
|
||||
ij_javascript_for_statement_new_line_after_left_paren = false
|
||||
ij_javascript_for_statement_right_paren_on_new_line = false
|
||||
ij_javascript_for_statement_wrap = off
|
||||
ij_javascript_force_quote_style = false
|
||||
ij_javascript_force_semicolon_style = false
|
||||
ij_javascript_function_expression_brace_style = end_of_line
|
||||
ij_javascript_if_brace_force = never
|
||||
ij_javascript_import_merge_members = global
|
||||
ij_javascript_import_prefer_absolute_path = global
|
||||
ij_javascript_import_sort_members = true
|
||||
ij_javascript_import_sort_module_name = false
|
||||
ij_javascript_import_use_node_resolution = true
|
||||
ij_javascript_imports_wrap = on_every_item
|
||||
ij_javascript_indent_case_from_switch = true
|
||||
ij_javascript_indent_chained_calls = true
|
||||
ij_javascript_indent_package_children = 0
|
||||
ij_javascript_jsx_attribute_value = braces
|
||||
ij_javascript_keep_blank_lines_in_code = 2
|
||||
ij_javascript_keep_first_column_comment = true
|
||||
ij_javascript_keep_indents_on_empty_lines = false
|
||||
ij_javascript_keep_line_breaks = true
|
||||
ij_javascript_keep_simple_blocks_in_one_line = false
|
||||
ij_javascript_keep_simple_methods_in_one_line = false
|
||||
ij_javascript_line_comment_add_space = true
|
||||
ij_javascript_line_comment_at_first_column = false
|
||||
ij_javascript_method_brace_style = end_of_line
|
||||
ij_javascript_method_call_chain_wrap = off
|
||||
ij_javascript_method_parameters_new_line_after_left_paren = false
|
||||
ij_javascript_method_parameters_right_paren_on_new_line = false
|
||||
ij_javascript_method_parameters_wrap = off
|
||||
ij_javascript_object_literal_wrap = on_every_item
|
||||
ij_javascript_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_javascript_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_javascript_place_assignment_sign_on_next_line = false
|
||||
ij_javascript_prefer_as_type_cast = false
|
||||
ij_javascript_prefer_explicit_types_function_expression_returns = false
|
||||
ij_javascript_prefer_explicit_types_function_returns = false
|
||||
ij_javascript_prefer_explicit_types_vars_fields = false
|
||||
ij_javascript_prefer_parameters_wrap = false
|
||||
ij_javascript_reformat_c_style_comments = false
|
||||
ij_javascript_space_after_colon = true
|
||||
ij_javascript_space_after_comma = true
|
||||
ij_javascript_space_after_dots_in_rest_parameter = false
|
||||
ij_javascript_space_after_generator_mult = true
|
||||
ij_javascript_space_after_property_colon = true
|
||||
ij_javascript_space_after_quest = true
|
||||
ij_javascript_space_after_type_colon = true
|
||||
ij_javascript_space_after_unary_not = false
|
||||
ij_javascript_space_before_async_arrow_lparen = true
|
||||
ij_javascript_space_before_catch_keyword = true
|
||||
ij_javascript_space_before_catch_left_brace = true
|
||||
ij_javascript_space_before_catch_parentheses = true
|
||||
ij_javascript_space_before_class_lbrace = true
|
||||
ij_javascript_space_before_class_left_brace = true
|
||||
ij_javascript_space_before_colon = true
|
||||
ij_javascript_space_before_comma = false
|
||||
ij_javascript_space_before_do_left_brace = true
|
||||
ij_javascript_space_before_else_keyword = true
|
||||
ij_javascript_space_before_else_left_brace = true
|
||||
ij_javascript_space_before_finally_keyword = true
|
||||
ij_javascript_space_before_finally_left_brace = true
|
||||
ij_javascript_space_before_for_left_brace = true
|
||||
ij_javascript_space_before_for_parentheses = true
|
||||
ij_javascript_space_before_for_semicolon = false
|
||||
ij_javascript_space_before_function_left_parenth = true
|
||||
ij_javascript_space_before_generator_mult = false
|
||||
ij_javascript_space_before_if_left_brace = true
|
||||
ij_javascript_space_before_if_parentheses = true
|
||||
ij_javascript_space_before_method_call_parentheses = false
|
||||
ij_javascript_space_before_method_left_brace = true
|
||||
ij_javascript_space_before_method_parentheses = false
|
||||
ij_javascript_space_before_property_colon = false
|
||||
ij_javascript_space_before_quest = true
|
||||
ij_javascript_space_before_switch_left_brace = true
|
||||
ij_javascript_space_before_switch_parentheses = true
|
||||
ij_javascript_space_before_try_left_brace = true
|
||||
ij_javascript_space_before_type_colon = false
|
||||
ij_javascript_space_before_unary_not = false
|
||||
ij_javascript_space_before_while_keyword = true
|
||||
ij_javascript_space_before_while_left_brace = true
|
||||
ij_javascript_space_before_while_parentheses = true
|
||||
ij_javascript_spaces_around_additive_operators = true
|
||||
ij_javascript_spaces_around_arrow_function_operator = true
|
||||
ij_javascript_spaces_around_assignment_operators = true
|
||||
ij_javascript_spaces_around_bitwise_operators = true
|
||||
ij_javascript_spaces_around_equality_operators = true
|
||||
ij_javascript_spaces_around_logical_operators = true
|
||||
ij_javascript_spaces_around_multiplicative_operators = true
|
||||
ij_javascript_spaces_around_relational_operators = true
|
||||
ij_javascript_spaces_around_shift_operators = true
|
||||
ij_javascript_spaces_around_unary_operator = false
|
||||
ij_javascript_spaces_within_array_initializer_brackets = false
|
||||
ij_javascript_spaces_within_brackets = false
|
||||
ij_javascript_spaces_within_catch_parentheses = false
|
||||
ij_javascript_spaces_within_for_parentheses = false
|
||||
ij_javascript_spaces_within_if_parentheses = false
|
||||
ij_javascript_spaces_within_imports = false
|
||||
ij_javascript_spaces_within_interpolation_expressions = false
|
||||
ij_javascript_spaces_within_method_call_parentheses = false
|
||||
ij_javascript_spaces_within_method_parentheses = false
|
||||
ij_javascript_spaces_within_object_literal_braces = false
|
||||
ij_javascript_spaces_within_object_type_braces = true
|
||||
ij_javascript_spaces_within_parentheses = false
|
||||
ij_javascript_spaces_within_switch_parentheses = false
|
||||
ij_javascript_spaces_within_type_assertion = false
|
||||
ij_javascript_spaces_within_union_types = true
|
||||
ij_javascript_spaces_within_while_parentheses = false
|
||||
ij_javascript_special_else_if_treatment = true
|
||||
ij_javascript_ternary_operation_signs_on_next_line = false
|
||||
ij_javascript_ternary_operation_wrap = off
|
||||
ij_javascript_union_types_wrap = on_every_item
|
||||
ij_javascript_use_chained_calls_group_indents = false
|
||||
ij_javascript_use_double_quotes = true
|
||||
ij_javascript_use_explicit_js_extension = auto
|
||||
ij_javascript_use_path_mapping = always
|
||||
ij_javascript_use_public_modifier = false
|
||||
ij_javascript_use_semicolon_after_statement = true
|
||||
ij_javascript_var_declaration_wrap = normal
|
||||
ij_javascript_while_brace_force = never
|
||||
ij_javascript_while_on_new_line = false
|
||||
ij_javascript_wrap_comments = false
|
||||
|
||||
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
|
||||
ij_json_array_wrapping = split_into_lines
|
||||
ij_json_keep_blank_lines_in_code = 0
|
||||
ij_json_keep_indents_on_empty_lines = false
|
||||
ij_json_keep_line_breaks = true
|
||||
ij_json_keep_trailing_comma = false
|
||||
ij_json_object_wrapping = split_into_lines
|
||||
ij_json_property_alignment = do_not_align
|
||||
ij_json_space_after_colon = true
|
||||
ij_json_space_after_comma = true
|
||||
ij_json_space_before_colon = false
|
||||
ij_json_space_before_comma = false
|
||||
ij_json_spaces_within_braces = false
|
||||
ij_json_spaces_within_brackets = false
|
||||
ij_json_wrap_long_lines = false
|
||||
|
||||
[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}]
|
||||
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
|
||||
ij_html_align_attributes = true
|
||||
ij_html_align_text = false
|
||||
ij_html_attribute_wrap = normal
|
||||
ij_html_block_comment_add_space = false
|
||||
ij_html_block_comment_at_first_column = true
|
||||
ij_html_do_not_align_children_of_min_lines = 0
|
||||
ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
|
||||
ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
|
||||
ij_html_enforce_quotes = false
|
||||
ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var
|
||||
ij_html_keep_blank_lines = 2
|
||||
ij_html_keep_indents_on_empty_lines = false
|
||||
ij_html_keep_line_breaks = true
|
||||
ij_html_keep_line_breaks_in_text = true
|
||||
ij_html_keep_whitespaces = false
|
||||
ij_html_keep_whitespaces_inside = span,pre,textarea
|
||||
ij_html_line_comment_at_first_column = true
|
||||
ij_html_new_line_after_last_attribute = never
|
||||
ij_html_new_line_before_first_attribute = never
|
||||
ij_html_quote_style = double
|
||||
ij_html_remove_new_line_before_tags = br
|
||||
ij_html_space_after_tag_name = false
|
||||
ij_html_space_around_equality_in_attribute = false
|
||||
ij_html_space_inside_empty_tag = false
|
||||
ij_html_text_wrap = normal
|
||||
|
||||
[{*.markdown,*.md}]
|
||||
ij_markdown_force_one_space_after_blockquote_symbol = true
|
||||
ij_markdown_force_one_space_after_header_symbol = true
|
||||
ij_markdown_force_one_space_after_list_bullet = true
|
||||
ij_markdown_force_one_space_between_words = true
|
||||
ij_markdown_format_tables = true
|
||||
ij_markdown_insert_quote_arrows_on_wrap = true
|
||||
ij_markdown_keep_indents_on_empty_lines = false
|
||||
ij_markdown_keep_line_breaks_inside_text_blocks = true
|
||||
ij_markdown_max_lines_around_block_elements = 1
|
||||
ij_markdown_max_lines_around_header = 1
|
||||
ij_markdown_max_lines_between_paragraphs = 1
|
||||
ij_markdown_min_lines_around_block_elements = 1
|
||||
ij_markdown_min_lines_around_header = 1
|
||||
ij_markdown_min_lines_between_paragraphs = 1
|
||||
ij_markdown_wrap_text_if_long = true
|
||||
ij_markdown_wrap_text_inside_blockquotes = true
|
||||
|
||||
[{*.properties,spring.handlers,spring.schemas}]
|
||||
ij_properties_align_group_field_declarations = false
|
||||
ij_properties_keep_blank_lines = false
|
||||
ij_properties_key_value_delimiter = equals
|
||||
ij_properties_spaces_around_key_value_delimiter = false
|
||||
|
||||
[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}]
|
||||
ij_toml_keep_indents_on_empty_lines = false
|
||||
|
||||
[{*.yaml,*.yml}]
|
||||
ij_yaml_align_values_properties = do_not_align
|
||||
ij_yaml_autoinsert_sequence_marker = true
|
||||
ij_yaml_block_mapping_on_new_line = false
|
||||
ij_yaml_indent_sequence_value = true
|
||||
ij_yaml_keep_indents_on_empty_lines = false
|
||||
ij_yaml_keep_line_breaks = true
|
||||
ij_yaml_sequence_on_new_line = false
|
||||
ij_yaml_space_before_colon = false
|
||||
ij_yaml_spaces_within_braces = true
|
||||
ij_yaml_spaces_within_brackets = true
|
||||
32
.env.example
32
.env.example
|
|
@ -1,15 +1,45 @@
|
|||
# Environment
|
||||
ENV=dev
|
||||
|
||||
# API
|
||||
ORIGIN=http://localhost:5173
|
||||
DOMAIN=localhost
|
||||
PORT=5173
|
||||
|
||||
# Database
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres
|
||||
DATABASE_USER='postgres'
|
||||
DATABASE_PASSWORD='postgres'
|
||||
DATABASE_HOST='localhost'
|
||||
DATABASE_PORT=5432
|
||||
DATABASE_DB='postgres'
|
||||
|
||||
# Drizzle
|
||||
LOG_LEVEL=debug
|
||||
DB_MIGRATING=false
|
||||
DB_SEEDING=false
|
||||
ADMIN_USERNAME=
|
||||
ADMIN_PASSWORD=
|
||||
|
||||
# Redis
|
||||
REDIS_URL=redis://localhost:6379
|
||||
|
||||
# Security - openssl rand -hex 32
|
||||
SIGNING_SECRET=
|
||||
|
||||
# Storage
|
||||
PUBLIC_IMAGE_URI=http://localhost:9000/dev
|
||||
STORAGE_BUCKET=dev
|
||||
STORAGE_URL=http://localhost:9000
|
||||
STORAGE_ACCESS_KEY=user
|
||||
STORAGE_SECRET_KEY=password
|
||||
|
||||
# Public
|
||||
PUBLIC_SITE_NAME=
|
||||
PUBLIC_SITE_URL='http://$DOMAIN:5173'
|
||||
|
||||
# Public Analytics
|
||||
PUBLIC_UMAMI_URL=""
|
||||
PUBLIC_UMAMI_ID=""
|
||||
|
||||
# quick setting for key-combo only
|
||||
SVELTE_INSPECTOR_TOGGLE=control-shift-i
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
23
.gitignore
vendored
23
.gitignore
vendored
|
|
@ -1,10 +1,27 @@
|
|||
.DS_Store
|
||||
test-results
|
||||
node_modules
|
||||
/build
|
||||
|
||||
# Output
|
||||
.output
|
||||
.vercel
|
||||
.netlify
|
||||
.wrangler
|
||||
/.svelte-kit
|
||||
/package
|
||||
/build
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
# Vite
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
|
||||
# Paraglide
|
||||
src/lib/paraglide
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
22.1.0
|
||||
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
22
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"useTabs": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||
}
|
||||
15
.storybook/main.js
Normal file
15
.storybook/main.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/** @type { import('@storybook/sveltekit').StorybookConfig } */
|
||||
const config = {
|
||||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|ts|svelte)"],
|
||||
addons: [
|
||||
"@storybook/addon-svelte-csf",
|
||||
"@storybook/addon-essentials",
|
||||
"@chromatic-com/storybook",
|
||||
"@storybook/addon-interactions",
|
||||
],
|
||||
framework: {
|
||||
name: "@storybook/sveltekit",
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
13
.storybook/preview.js
Normal file
13
.storybook/preview.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/** @type { import('@storybook/svelte').Preview } */
|
||||
const preview = {
|
||||
parameters: {
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default preview;
|
||||
65
biome.json
Normal file
65
biome.json
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||
"vcs": {
|
||||
"enabled": false,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": false
|
||||
},
|
||||
"files": { "ignoreUnknown": false, "ignore": [] },
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"formatWithErrors": false,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineEnding": "lf",
|
||||
"lineWidth": 150,
|
||||
"attributePosition": "auto",
|
||||
"ignore": [
|
||||
"**/.DS_Store",
|
||||
"**/node_modules",
|
||||
"./build",
|
||||
"./.svelte-kit",
|
||||
"./package",
|
||||
"**/.env",
|
||||
"**/.env.*",
|
||||
"**/pnpm-lock.yaml",
|
||||
"**/package-lock.json",
|
||||
"**/yarn.lock",
|
||||
"**/paraglide/**"
|
||||
]
|
||||
},
|
||||
"organizeImports": { "enabled": true },
|
||||
"linter": { "enabled": true, "rules": { "recommended": true } },
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"jsxQuoteStyle": "single",
|
||||
"quoteProperties": "asNeeded",
|
||||
"trailingCommas": "all",
|
||||
"indentStyle": "space",
|
||||
"lineEnding": "lf",
|
||||
"lineWidth": 150,
|
||||
"semicolons": "always",
|
||||
"arrowParentheses": "always",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": false,
|
||||
"quoteStyle": "single",
|
||||
"attributePosition": "auto"
|
||||
},
|
||||
"parser": {
|
||||
"unsafeParameterDecoratorsEnabled": true
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"include": ["*.svelte"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"style": {
|
||||
"useConst": "off",
|
||||
"useImportType": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"$schema": "https://shadcn-svelte.com/schema.json",
|
||||
"$schema": "https://next.shadcn-svelte.com/schema.json",
|
||||
"style": "default",
|
||||
"tailwind": {
|
||||
"config": "tailwind.config.ts",
|
||||
|
|
@ -8,7 +8,10 @@
|
|||
},
|
||||
"aliases": {
|
||||
"components": "$lib/components",
|
||||
"utils": "$lib/utils/ui"
|
||||
"utils": "$lib/utils",
|
||||
"ui": "$lib/components/ui",
|
||||
"hooks": "$lib/hooks"
|
||||
},
|
||||
"typescript": true
|
||||
"typescript": true,
|
||||
"registry": "https://next.shadcn-svelte.com/registry"
|
||||
}
|
||||
|
|
@ -1,40 +1,43 @@
|
|||
version: '3.8'
|
||||
version: "3.8"
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
container_name: tofu_postgres
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- '5432:5432'
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/data
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
redis:
|
||||
image: redis:latest
|
||||
container_name: tofu_redis
|
||||
ports:
|
||||
- '6379:6379'
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
minio:
|
||||
image: docker.io/bitnami/minio
|
||||
container_name: tofu_minio
|
||||
ports:
|
||||
- '9000:9000'
|
||||
- '9001:9001'
|
||||
- "9000:9000"
|
||||
- "9001:9001"
|
||||
networks:
|
||||
- minionetwork
|
||||
- app-network
|
||||
volumes:
|
||||
- 'minio_data:/data'
|
||||
- "minio_data:/data"
|
||||
environment:
|
||||
- MINIO_ROOT_USER=user
|
||||
- MINIO_ROOT_PASSWORD=password
|
||||
- MINIO_DEFAULT_BUCKETS=dev
|
||||
|
||||
mailpit:
|
||||
image: axllent/mailpit
|
||||
container_name: tofu_mailpit
|
||||
volumes:
|
||||
- mailpit_data:/data
|
||||
ports:
|
||||
|
|
@ -45,6 +48,8 @@ services:
|
|||
MP_DATABASE: /data/mailpit.db
|
||||
MP_SMTP_AUTH_ACCEPT_ANY: 1
|
||||
MP_SMTP_AUTH_ALLOW_INSECURE: 1
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
|
@ -54,5 +59,5 @@ volumes:
|
|||
driver: local
|
||||
|
||||
networks:
|
||||
minionetwork:
|
||||
app-network:
|
||||
driver: bridge
|
||||
6
e2e/demo.test.ts
Normal file
6
e2e/demo.test.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { expect, test } from '@playwright/test';
|
||||
|
||||
test('home page has expected h1', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await expect(page.locator('h1')).toBeVisible();
|
||||
});
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
import js from '@eslint/js';
|
||||
import ts from 'typescript-eslint';
|
||||
import svelte from 'eslint-plugin-svelte';
|
||||
import prettier from 'eslint-config-prettier';
|
||||
import globals from 'globals';
|
||||
|
||||
/** @type {import('eslint').Linter.FlatConfig[]} */
|
||||
export default [
|
||||
js.configs.recommended,
|
||||
...ts.configs.recommended,
|
||||
...svelte.configs['flat/recommended'],
|
||||
prettier,
|
||||
...svelte.configs['flat/prettier'],
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*.svelte'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
parser: ts.parser
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
ignores: ['build/', '.svelte-kit/', 'dist/']
|
||||
}
|
||||
];
|
||||
4
messages/en.json
Normal file
4
messages/en.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://inlang.com/schema/inlang-message-format",
|
||||
"hello_world": "Hello, {name} from en!"
|
||||
}
|
||||
4
messages/es.json
Normal file
4
messages/es.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "https://inlang.com/schema/inlang-message-format",
|
||||
"hello_world": "Hello, {name} from es!"
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
upstream minio_console {
|
||||
server ${MINIO_HOST}:${MINIO_CONSOLE_PORT};
|
||||
}
|
||||
|
||||
server {
|
||||
listen ${PORT};
|
||||
|
||||
# Allow special characters in headers
|
||||
ignore_invalid_headers off;
|
||||
# Allow any size file to be uploaded.
|
||||
# Set to a value such as 1000m; to restrict file size to a specific value
|
||||
client_max_body_size 0;
|
||||
# Disable buffering
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
|
||||
location / {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
|
||||
# This is necessary to pass the correct IP to be hashed
|
||||
real_ip_header X-Real-IP;
|
||||
|
||||
proxy_connect_timeout 300;
|
||||
|
||||
# To support websockets in MinIO versions released after January 2023
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
# Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)
|
||||
# Uncomment the following line to set the Origin request to an empty string
|
||||
# proxy_set_header Origin '';
|
||||
|
||||
chunked_transfer_encoding off;
|
||||
|
||||
proxy_pass http://minio_console; # This uses the upstream directive definition to load balance
|
||||
}
|
||||
}
|
||||
164
package.json
164
package.json
|
|
@ -1,90 +1,120 @@
|
|||
{
|
||||
"name": "taro-stack",
|
||||
"name": "adelie-stack",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
"db:migrate": "tsx src/lib/server/api/databases/postgres/migrate.ts",
|
||||
"db:seed": "tsx src/lib/server/api/databases/postgres/seed.ts",
|
||||
"db:studio": "drizzle-kit studio --verbose",
|
||||
"dev": "vite dev",
|
||||
"dev": "NODE_OPTIONS=\"--inspect\" vite dev --host",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"test": "npm run test:integration && npm run test:unit",
|
||||
"test:unit": "vitest",
|
||||
"test": "pnpm test:unit -- --run && pnpm test:e2e",
|
||||
"test:e2e": "playwright test",
|
||||
"test:ui": "svelte-kit sync && playwright test --ui",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"initialize": "pnpm install && docker-compose up --no-recreate -d && pnpm db:migrate",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write .",
|
||||
"test:integration": "playwright test",
|
||||
"test:unit": "vitest"
|
||||
"initialize": "pnpm install && docker compose up --no-recreate -d && pnpm db:migrate && pnpm db:seed",
|
||||
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||
"format": "prettier --plugin-search-dir . --write .",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"site:update": "pnpm update -i -L"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/client-s3": "^3.651.0",
|
||||
"@hono/zod-validator": "^0.2.2",
|
||||
"@lucia-auth/adapter-drizzle": "^1.1.0",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@playwright/test": "^1.47.0",
|
||||
"@sveltejs/adapter-node": "^5.2.2",
|
||||
"@sveltejs/kit": "^2.5.26",
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.7",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/node": "^22.5.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.5.0",
|
||||
"@typescript-eslint/parser": "^8.5.0",
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@chromatic-com/storybook": "^3.2.3",
|
||||
"@dicebear/collection": "^9.2.2",
|
||||
"@dicebear/converter": "^9.2.2",
|
||||
"@dicebear/core": "^9.2.2",
|
||||
"@faker-js/faker": "^9.3.0",
|
||||
"@playwright/test": "^1.45.3",
|
||||
"@storybook/addon-essentials": "^8.4.7",
|
||||
"@storybook/addon-interactions": "^8.4.7",
|
||||
"@storybook/addon-svelte-csf": "^5.0.0-next.21",
|
||||
"@storybook/blocks": "^8.4.7",
|
||||
"@storybook/svelte": "^8.4.7",
|
||||
"@storybook/sveltekit": "^8.4.7",
|
||||
"@storybook/test": "^8.4.7",
|
||||
"@sveltejs/adapter-node": "^5.2.9",
|
||||
"@sveltejs/enhanced-img": "^0.4.4",
|
||||
"@sveltejs/kit": "^2.15.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@types/cookie": "^1.0.0",
|
||||
"@types/node": "^22.10.2",
|
||||
"@types/pg": "^8.11.10",
|
||||
"@types/pg-pool": "^2.0.6",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"arctic": "^1.9.2",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"bits-ui": "1.0.0-next.76",
|
||||
"bullmq": "^5.13.0",
|
||||
"chalk": "^5.3.0",
|
||||
"dotenv-cli": "^7.4.2",
|
||||
"drizzle-kit": "^0.26.2",
|
||||
"drizzle-orm": "^0.35.1",
|
||||
"eslint": "^9.10.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.43.0",
|
||||
"hono": "^4.6.1",
|
||||
"ioredis": "^5.4.1",
|
||||
"lucia": "^3.2.0",
|
||||
"lucide-svelte": "^0.441.0",
|
||||
"oslo": "^1.2.1",
|
||||
"pg": "^8.12.0",
|
||||
"postcss": "^8.4.45",
|
||||
"postgres": "^3.4.4",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"prettier-plugin-tailwindcss": "^0.6.6",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"svelte": "5.0.0-next.164",
|
||||
"svelte-check": "^4.0.2",
|
||||
"svelte-dnd-action": "^0.9.50",
|
||||
"svelte-eslint-parser": "^0.41.0",
|
||||
"sveltekit-search-params": "^3.0.0",
|
||||
"sveltekit-superforms": "^2.17.0",
|
||||
"tailwindcss": "^3.4.11",
|
||||
"tsyringe": "^4.8.0",
|
||||
"typescript": "^5.6.2",
|
||||
"vite": "^5.4.4",
|
||||
"vitest": "^2.1.0",
|
||||
"zod": "^3.23.8"
|
||||
"clsx": "^2.1.1",
|
||||
"drizzle-kit": "^0.30.1",
|
||||
"formsnap": "^2.0.0",
|
||||
"lucide-svelte": "^0.469.0",
|
||||
"mode-watcher": "^0.5.0",
|
||||
"storybook": "^8.4.7",
|
||||
"svelte": "^5.16.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"svelte-meta-tags": "^4.0.4",
|
||||
"svelte-preprocess": "^6.0.3",
|
||||
"svelte-sequential-preprocessor": "^2.0.2",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"sveltekit-flash-message": "^2.4.4",
|
||||
"sveltekit-superforms": "^2.22.1",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tailwind-variants": "^0.3.0",
|
||||
"tailwindcss": "^3.4.9",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^6.0.6",
|
||||
"vitest": "^2.0.4",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@hono/swagger-ui": "^0.5.0",
|
||||
"@hono/zod-openapi": "^0.18.3",
|
||||
"@hono/zod-validator": "^0.4.2",
|
||||
"@inlang/paraglide-sveltekit": "^0.15.0",
|
||||
"@internationalized/date": "^3.5.5",
|
||||
"bits-ui": "^0.21.13",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk-sv": "^0.0.18",
|
||||
"embla-carousel-svelte": "^8.2.1",
|
||||
"formsnap": "^1.0.1",
|
||||
"hono-rate-limiter": "^0.4.0",
|
||||
"mode-watcher": "^0.4.1",
|
||||
"paneforge": "^0.0.5",
|
||||
"@needle-di/core": "^0.8.4",
|
||||
"@oslojs/binary": "^1.0.0",
|
||||
"@oslojs/crypto": "^1.0.1",
|
||||
"@oslojs/encoding": "^1.1.0",
|
||||
"@oslojs/jwt": "^0.3.0",
|
||||
"@oslojs/oauth2": "^0.5.0",
|
||||
"@oslojs/otp": "^1.0.0",
|
||||
"@oslojs/webauthn": "^1.0.0",
|
||||
"@scalar/hono-api-reference": "^0.5.162",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"arctic": "^2.3.3",
|
||||
"argon2": "^0.41.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"dotenv": "^16.4.7",
|
||||
"drizzle-orm": "^0.38.3",
|
||||
"drizzle-zod": "^0.6.1",
|
||||
"hono": "^4.6.15",
|
||||
"hono-pino": "^0.7.0",
|
||||
"hono-rate-limiter": "^0.4.2",
|
||||
"hono-zod-openapi": "^0.5.0",
|
||||
"ioredis": "^5.4.2",
|
||||
"minio": "^8.0.3",
|
||||
"nanoid": "^5.0.9",
|
||||
"pg": "^8.13.1",
|
||||
"pg-pool": "^3.7.0",
|
||||
"pino": "^9.6.0",
|
||||
"pino-pretty": "^13.0.0",
|
||||
"postgres": "^3.4.4",
|
||||
"rate-limit-redis": "^4.2.0",
|
||||
"redis": "^4.7.0",
|
||||
"redis-om": "^0.4.6",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwind-variants": "^0.2.1",
|
||||
"vaul-svelte": "^0.3.2"
|
||||
"sharp": "^0.33.5",
|
||||
"sonner": "^1.7.1",
|
||||
"stoker": "^1.4.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
import { defineConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
webServer: {
|
||||
command: 'npm run build && npm run preview',
|
||||
port: 4173
|
||||
},
|
||||
testDir: 'tests',
|
||||
testMatch: /(.+\.)?(test|spec)\.[jt]s/
|
||||
};
|
||||
export default defineConfig({
|
||||
webServer: {
|
||||
command: 'npm run build && npm run preview',
|
||||
port: 4173
|
||||
},
|
||||
|
||||
export default config;
|
||||
testDir: 'e2e'
|
||||
});
|
||||
|
|
|
|||
8532
pnpm-lock.yaml
8532
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
1
project.inlang/.gitignore
vendored
Normal file
1
project.inlang/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
cache
|
||||
1
project.inlang/project_id
Normal file
1
project.inlang/project_id
Normal file
|
|
@ -0,0 +1 @@
|
|||
eb7d81211e6faa5e843476a33150228f5db02e3c62748d6eff4e45b709691d18
|
||||
20
project.inlang/settings.json
Normal file
20
project.inlang/settings.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"$schema": "https://inlang.com/schema/project-settings",
|
||||
"modules": [
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@1/dist/index.js",
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-identical-pattern@1/dist/index.js",
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@1/dist/index.js",
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@1/dist/index.js",
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-valid-js-identifier@1/dist/index.js",
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@2/dist/index.js",
|
||||
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@0/dist/index.js"
|
||||
],
|
||||
"plugin.inlang.messageFormat": {
|
||||
"pathPattern": "./messages/{languageTag}.json"
|
||||
},
|
||||
"sourceLanguageTag": "en",
|
||||
"languageTags": [
|
||||
"en",
|
||||
"es"
|
||||
]
|
||||
}
|
||||
101
render.yaml
101
render.yaml
|
|
@ -1,101 +0,0 @@
|
|||
services:
|
||||
# Web
|
||||
- type: web
|
||||
name: web
|
||||
runtime: node
|
||||
region: oregon # optional (defaults to oregon)
|
||||
plan: starter # optional (defaults to starter instance type)
|
||||
branch: main # optional (defaults to master)
|
||||
buildCommand: npm install --force && npm run build
|
||||
startCommand: npm run db:migrate && node build/index.js
|
||||
healthCheckPath: /
|
||||
envVars:
|
||||
- key: STORAGE_API_SECRET_KEY
|
||||
fromService:
|
||||
name: minio-server
|
||||
type: web
|
||||
property: MINIO_ROOT_PASSWORD
|
||||
- key: STORAGE_ACCESS_KEY
|
||||
fromService:
|
||||
name: minio-server
|
||||
type: web
|
||||
property: MINIO_ROOT_USER
|
||||
- key: STORAGE_API_URL
|
||||
fromService:
|
||||
name: minio-server
|
||||
type: web
|
||||
property: connectionString
|
||||
- key: DATABASE_URL
|
||||
fromDatabase:
|
||||
name: tofustack
|
||||
property: connectionString
|
||||
- key: REDIS_URL
|
||||
fromService:
|
||||
name: redis
|
||||
type: redis
|
||||
property: connectionString
|
||||
- key: PUBLIC_ORIGIN
|
||||
fromService:
|
||||
name: web
|
||||
type: web
|
||||
property: host
|
||||
# Redis
|
||||
- type: redis
|
||||
name: redis
|
||||
ipAllowList: [] # Only allow internal connections
|
||||
|
||||
# MinIO Server
|
||||
- type: web
|
||||
name: minio-server
|
||||
healthCheckPath: /minio/health/liveweb
|
||||
runtime: image
|
||||
image:
|
||||
url: docker.io/minio/minio:latest
|
||||
dockerCommand: minio server /data --address $HOST:$PORT --console-address $HOST:$CONSOLE_PORT
|
||||
# Use the following 'dockerCommand' if removing the 'minio-console'
|
||||
# web service
|
||||
# dockerCommand: minio server /data --address $HOST:$PORT
|
||||
autoDeploy: false
|
||||
disk:
|
||||
name: data
|
||||
mountPath: /data
|
||||
envVars:
|
||||
- key: MINIO_ROOT_USER
|
||||
generateValue: true
|
||||
- key: MINIO_ROOT_PASSWORD
|
||||
generateValue: true
|
||||
- key: HOST
|
||||
value: "0.0.0.0"
|
||||
- key: PORT
|
||||
value: 9000
|
||||
- key: CONSOLE_PORT
|
||||
value: 9090
|
||||
# Uncomment the following key/value pair if you are removing the
|
||||
# 'minio-console' web service
|
||||
# - key: MINIO_BROWSER
|
||||
# value: "off"
|
||||
# MinIO Console
|
||||
- type: web
|
||||
name: minio-console
|
||||
runtime: docker
|
||||
dockerContext: /
|
||||
dockerfilePath: ./Dockerfile.minio
|
||||
autoDeploy: false
|
||||
envVars:
|
||||
- key: PORT
|
||||
value: 10000
|
||||
- key: MINIO_HOST
|
||||
fromService:
|
||||
name: minio-server
|
||||
type: web
|
||||
property: host
|
||||
- key: MINIO_CONSOLE_PORT
|
||||
fromService:
|
||||
name: minio-server
|
||||
type: web
|
||||
envVarKey: CONSOLE_PORT
|
||||
|
||||
databases:
|
||||
- name: db
|
||||
databaseName: tofustack
|
||||
ipAllowList: []
|
||||
37
src/app.css
37
src/app.css
|
|
@ -6,65 +6,62 @@
|
|||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
|
||||
--primary: 222.2 47.4% 11.2%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
|
||||
--accent: 210 40% 96.1%;
|
||||
--accent-foreground: 222.2 47.4% 11.2%;
|
||||
|
||||
--destructive: 0 72.2% 50.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: 222.2 84% 4.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
--sidebar-background: 0 0% 98%;
|
||||
--sidebar-foreground: 240 5.3% 26.1%;
|
||||
--sidebar-primary: 240 5.9% 10%;
|
||||
--sidebar-primary-foreground: 0 0% 98%;
|
||||
--sidebar-accent: 240 4.8% 95.9%;
|
||||
--sidebar-accent-foreground: 240 5.9% 10%;
|
||||
--sidebar-border: 220 13% 91%;
|
||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
|
||||
--primary: 210 40% 98%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--ring: hsl(212.7,26.8%,83.9);
|
||||
--ring: 212.7 26.8% 83.9%;
|
||||
--sidebar-background: 240 5.9% 10%;
|
||||
--sidebar-foreground: 240 4.8% 95.9%;
|
||||
--sidebar-primary: 224.3 76.3% 48%;
|
||||
--sidebar-primary-foreground: 0 0% 100%;
|
||||
--sidebar-accent: 240 3.7% 15.9%;
|
||||
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
||||
--sidebar-border: 240 3.7% 15.9%;
|
||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
29
src/app.d.ts
vendored
29
src/app.d.ts
vendored
|
|
@ -7,24 +7,41 @@ import type { Security } from '$lib/utils/security';
|
|||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
interface PageData {
|
||||
flash?: {
|
||||
type: 'success' | 'error' | 'info';
|
||||
message: string;
|
||||
data?: Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
interface Locals {
|
||||
api: ApiClient['api'];
|
||||
parseApiResponse: typeof parseApiResponse;
|
||||
getAuthedUser: () => Promise<Returned<User> | null>;
|
||||
getAuthedUserOrThrow: (redirectTo: string) => Promise<Returned<User>>;
|
||||
}
|
||||
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
namespace Superforms {
|
||||
type Message = {
|
||||
type: 'error' | 'success',
|
||||
text: string
|
||||
type: 'error' | 'success' | 'info';
|
||||
text: string;
|
||||
}
|
||||
}
|
||||
interface Error {
|
||||
code?: string;
|
||||
errorId?: string;
|
||||
}
|
||||
}
|
||||
interface Document {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
startViewTransition: (callback: never) => void; // Add your custom property/method here
|
||||
}
|
||||
}
|
||||
|
||||
export { };
|
||||
// THIS IS IMPORTANT!!!
|
||||
// biome-ignore lint/complexity/noUselessEmptyExport: <explanation>
|
||||
// biome-ignore lint/style/useExportType: <explanation>
|
||||
export {};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang="%paraglide.lang%" dir="%paraglide.textDirection%">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
|
|
|
|||
|
|
@ -1,32 +1,37 @@
|
|||
import 'reflect-metadata'
|
||||
import { hc } from 'hono/client';
|
||||
import { redirect, type Handle } from '@sveltejs/kit';
|
||||
import { redirect, type Handle, type ServerInit } from '@sveltejs/kit';
|
||||
import { sequence } from '@sveltejs/kit/hooks';
|
||||
import type { ApiRoutes } from '$lib/server/api';
|
||||
import { parseApiResponse } from '$lib/utils/api';
|
||||
import { startServer } from '$lib/server/api';
|
||||
import { honoClient, parseApiResponse } from '$lib/utils/api';
|
||||
import { StatusCodes } from '$lib/constants/status-codes';
|
||||
import { i18n } from './lib/i18n';
|
||||
|
||||
const handleParaglide: Handle = i18n.handle();
|
||||
|
||||
export const app = await startServer();
|
||||
|
||||
const apiClient: Handle = async ({ event, resolve }) => {
|
||||
/* ------------------------------ Register api ------------------------------ */
|
||||
const { api } = hc<ApiRoutes>('/', {
|
||||
const { api } = honoClient({
|
||||
fetch: event.fetch,
|
||||
headers: {
|
||||
'x-forwarded-for': event.getClientAddress(),
|
||||
host: event.request.headers.get('host') || ''
|
||||
}
|
||||
'x-forwarded-for': event.url.host.includes('sveltekit-prerender') ? '127.0.0.1' : event.getClientAddress(),
|
||||
host: event.request.headers.get('host') || '',
|
||||
},
|
||||
});
|
||||
|
||||
/* ----------------------------- Auth functions ----------------------------- */
|
||||
async function getAuthedUser() {
|
||||
const { data } = await api.iam.me.$get().then(parseApiResponse)
|
||||
return data && data.user;
|
||||
}
|
||||
const { data } = await api.users.me.$get().then(parseApiResponse);
|
||||
return { user: data?.user, session: data?.session };
|
||||
}
|
||||
|
||||
async function getAuthedUserOrThrow(redirectTo = '/') {
|
||||
const { data } = await api.iam.me.$get().then(parseApiResponse);
|
||||
if (!data || !data.user) throw redirect(StatusCodes.TEMPORARY_REDIRECT, redirectTo);
|
||||
return data?.user;
|
||||
}
|
||||
async function getAuthedUserOrThrow() {
|
||||
const { data } = await api.users.me.$get().then(parseApiResponse);
|
||||
if (!data || !data.user) {
|
||||
throw redirect(StatusCodes.TEMPORARY_REDIRECT, '/');
|
||||
}
|
||||
return data?.user;
|
||||
}
|
||||
|
||||
/* ------------------------------ Set contexts ------------------------------ */
|
||||
event.locals.api = api;
|
||||
|
|
@ -39,4 +44,4 @@ const apiClient: Handle = async ({ event, resolve }) => {
|
|||
return response;
|
||||
};
|
||||
|
||||
export const handle = sequence(apiClient);
|
||||
export const handle: Handle = sequence(apiClient, handleParaglide);
|
||||
|
|
|
|||
2
src/hooks.ts
Normal file
2
src/hooks.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import { i18n } from '$lib/i18n';
|
||||
export const reroute = i18n.reroute();
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { cn } from '$lib/utils/ui';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
interface Props extends HTMLAttributes<HTMLDivElement> {
|
||||
children: Snippet;
|
||||
}
|
||||
|
||||
let { class: classNames, children, ...restProps }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div {...restProps} class={cn('mx-auto w-full max-w-6xl px-0 md:px-6', classNames)}>
|
||||
{@render children()}
|
||||
</div>
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { cn } from '$lib/utils/ui';
|
||||
import { PinInput, type PinInputProps } from 'bits-ui';
|
||||
|
||||
interface Props extends Omit<PinInputProps, 'value'> {
|
||||
value: string;
|
||||
inputCount?: number;
|
||||
}
|
||||
|
||||
let { value = $bindable(), inputCount = 6, ...rest }: Props = $props();
|
||||
let pin = $state<string[] | undefined>(value?.split('') ?? []);
|
||||
let inputs = $derived(Array(inputCount).fill(null));
|
||||
|
||||
$effect(() => {
|
||||
value = pin?.join('') ?? '';
|
||||
});
|
||||
</script>
|
||||
|
||||
<PinInput.Root
|
||||
{...rest}
|
||||
bind:value={pin}
|
||||
class={cn('flex items-center gap-2', rest.class)}
|
||||
type="text"
|
||||
placeholder=""
|
||||
>
|
||||
{#each inputs as _}
|
||||
<PinInput.Input
|
||||
class="flex h-14 w-10 rounded-md border border-input bg-background px-3 py-2 text-center text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
{/each}
|
||||
<PinInput.HiddenInput />
|
||||
</PinInput.Root>
|
||||
25
src/lib/components/theme-dropdown.svelte
Normal file
25
src/lib/components/theme-dropdown.svelte
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<script lang="ts">
|
||||
import Moon from 'lucide-svelte/icons/moon';
|
||||
import Sun from 'lucide-svelte/icons/sun';
|
||||
|
||||
import { buttonVariants } from '$lib/components/ui/button/index.js';
|
||||
import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index.js';
|
||||
import { resetMode, setMode } from 'mode-watcher';
|
||||
</script>
|
||||
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger class={buttonVariants({ variant: 'outline', size: 'icon' })}>
|
||||
<Sun
|
||||
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
|
||||
/>
|
||||
<Moon
|
||||
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
|
||||
/>
|
||||
<span class="sr-only">Toggle theme</span>
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Content align="end">
|
||||
<DropdownMenu.Item onclick={() => setMode('light')}>Light</DropdownMenu.Item>
|
||||
<DropdownMenu.Item onclick={() => setMode('dark')}>Dark</DropdownMenu.Item>
|
||||
<DropdownMenu.Item onclick={() => resetMode()}>System</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Root>
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||
import { slide } from "svelte/transition";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AccordionPrimitive.ContentProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let transition: $$Props["transition"] = slide;
|
||||
export let transitionConfig: $$Props["transitionConfig"] = {
|
||||
duration: 200,
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AccordionPrimitive.Content
|
||||
class={cn("overflow-hidden text-sm transition-all", className)}
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
{...$$restProps}
|
||||
>
|
||||
<div class="pb-4 pt-0">
|
||||
<slot />
|
||||
</div>
|
||||
</AccordionPrimitive.Content>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AccordionPrimitive.ItemProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let value: $$Props["value"];
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AccordionPrimitive.Item {value} class={cn("border-b", className)} {...$$restProps}>
|
||||
<slot />
|
||||
</AccordionPrimitive.Item>
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||
import ChevronDown from "lucide-svelte/icons/chevron-down";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AccordionPrimitive.TriggerProps;
|
||||
type $$Events = AccordionPrimitive.TriggerEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let level: AccordionPrimitive.HeaderProps["level"] = 3;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AccordionPrimitive.Header {level} class="flex">
|
||||
<AccordionPrimitive.Trigger
|
||||
class={cn(
|
||||
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
>
|
||||
<slot />
|
||||
<ChevronDown class="h-4 w-4 transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import { Accordion as AccordionPrimitive } from "bits-ui";
|
||||
import Content from "./accordion-content.svelte";
|
||||
import Item from "./accordion-item.svelte";
|
||||
import Trigger from "./accordion-trigger.svelte";
|
||||
const Root = AccordionPrimitive.Root;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Content,
|
||||
Item,
|
||||
Trigger,
|
||||
//
|
||||
Root as Accordion,
|
||||
Content as AccordionContent,
|
||||
Item as AccordionItem,
|
||||
Trigger as AccordionTrigger,
|
||||
};
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
import { buttonVariants } from "$lib/components/ui/button/index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AlertDialogPrimitive.ActionProps;
|
||||
type $$Events = AlertDialogPrimitive.ActionEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Action
|
||||
class={cn(buttonVariants(), className)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
let:builder
|
||||
>
|
||||
<slot {builder} />
|
||||
</AlertDialogPrimitive.Action>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
import { buttonVariants } from "$lib/components/ui/button/index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AlertDialogPrimitive.CancelProps;
|
||||
type $$Events = AlertDialogPrimitive.CancelEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Cancel
|
||||
class={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
let:builder
|
||||
>
|
||||
<slot {builder} />
|
||||
</AlertDialogPrimitive.Cancel>
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
import * as AlertDialog from "./index.js";
|
||||
import { cn, flyAndScale } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AlertDialogPrimitive.ContentProps;
|
||||
|
||||
export let transition: $$Props["transition"] = flyAndScale;
|
||||
export let transitionConfig: $$Props["transitionConfig"] = undefined;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialog.Portal>
|
||||
<AlertDialog.Overlay />
|
||||
<AlertDialogPrimitive.Content
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn(
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg md:w-full",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Content>
|
||||
</AlertDialog.Portal>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AlertDialogPrimitive.DescriptionProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Description
|
||||
class={cn("text-sm text-muted-foreground", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Description>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
import { fade } from "svelte/transition";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AlertDialogPrimitive.OverlayProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let transition: $$Props["transition"] = fade;
|
||||
export let transitionConfig: $$Props["transitionConfig"] = {
|
||||
duration: 150,
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Overlay
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn("fixed inset-0 z-50 bg-background/80 backdrop-blur-sm ", className)}
|
||||
{...$$restProps}
|
||||
/>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
|
||||
type $$Props = AlertDialogPrimitive.PortalProps;
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Portal {...$$restProps}>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Portal>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AlertDialogPrimitive.TitleProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let level: $$Props["level"] = "h3";
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AlertDialogPrimitive.Title class={cn("text-lg font-semibold", className)} {level} {...$$restProps}>
|
||||
<slot />
|
||||
</AlertDialogPrimitive.Title>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
|
||||
|
||||
import Title from "./alert-dialog-title.svelte";
|
||||
import Action from "./alert-dialog-action.svelte";
|
||||
import Cancel from "./alert-dialog-cancel.svelte";
|
||||
import Portal from "./alert-dialog-portal.svelte";
|
||||
import Footer from "./alert-dialog-footer.svelte";
|
||||
import Header from "./alert-dialog-header.svelte";
|
||||
import Overlay from "./alert-dialog-overlay.svelte";
|
||||
import Content from "./alert-dialog-content.svelte";
|
||||
import Description from "./alert-dialog-description.svelte";
|
||||
|
||||
const Root = AlertDialogPrimitive.Root;
|
||||
const Trigger = AlertDialogPrimitive.Trigger;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Title,
|
||||
Action,
|
||||
Cancel,
|
||||
Portal,
|
||||
Footer,
|
||||
Header,
|
||||
Trigger,
|
||||
Overlay,
|
||||
Content,
|
||||
Description,
|
||||
//
|
||||
Root as AlertDialog,
|
||||
Title as AlertDialogTitle,
|
||||
Action as AlertDialogAction,
|
||||
Cancel as AlertDialogCancel,
|
||||
Portal as AlertDialogPortal,
|
||||
Footer as AlertDialogFooter,
|
||||
Header as AlertDialogHeader,
|
||||
Trigger as AlertDialogTrigger,
|
||||
Overlay as AlertDialogOverlay,
|
||||
Content as AlertDialogContent,
|
||||
Description as AlertDialogDescription,
|
||||
};
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
<script lang="ts">
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||
</script>
|
||||
|
||||
<div class={cn("text-sm [&_p]:leading-relaxed", className)} {...$$restProps}>
|
||||
<slot />
|
||||
<div bind:this={ref} class={cn("text-sm [&_p]:leading-relaxed", className)} {...restProps}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,25 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import type { HeadingLevel } from "./index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
|
||||
level?: HeadingLevel;
|
||||
};
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let level: $$Props["level"] = "h5";
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
level = 5,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={level}
|
||||
<div
|
||||
role="heading"
|
||||
aria-level={level}
|
||||
bind:this={ref}
|
||||
class={cn("mb-1 font-medium leading-none tracking-tight", className)}
|
||||
{...$$restProps}
|
||||
{...restProps}
|
||||
>
|
||||
<slot />
|
||||
</svelte:element>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,39 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { type Variant, alertVariants } from "./index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
<script lang="ts" module>
|
||||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement> & {
|
||||
variant?: Variant;
|
||||
};
|
||||
export const alertVariants = tv({
|
||||
base: "[&>svg]:text-foreground relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-7",
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-background text-foreground",
|
||||
destructive:
|
||||
"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
});
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let variant: $$Props["variant"] = "default";
|
||||
export { className as class };
|
||||
export type AlertVariant = VariantProps<typeof alertVariants>["variant"];
|
||||
</script>
|
||||
|
||||
<div class={cn(alertVariants({ variant }), className)} {...$$restProps} role="alert">
|
||||
<slot />
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
variant = "default",
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||
variant?: AlertVariant;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<div bind:this={ref} class={cn(alertVariants({ variant }), className)} {...restProps} role="alert">
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,26 +1,7 @@
|
|||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
|
||||
import Root from "./alert.svelte";
|
||||
import Description from "./alert-description.svelte";
|
||||
import Title from "./alert-title.svelte";
|
||||
|
||||
export const alertVariants = tv({
|
||||
base: "relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
||||
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-background text-foreground",
|
||||
destructive:
|
||||
"border-destructive/50 text-destructive text-destructive dark:border-destructive [&>svg]:text-destructive",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
});
|
||||
|
||||
export type Variant = VariantProps<typeof alertVariants>["variant"];
|
||||
export type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
||||
export { alertVariants, type AlertVariant } from "./alert.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { AspectRatio as AspectRatioPrimitive } from "bits-ui";
|
||||
|
||||
type $$Props = AspectRatioPrimitive.Props;
|
||||
|
||||
export let ratio: $$Props["ratio"] = 4 / 3;
|
||||
</script>
|
||||
|
||||
<AspectRatioPrimitive.Root {ratio} {...$$restProps}>
|
||||
<slot />
|
||||
</AspectRatioPrimitive.Root>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import Root from "./aspect-ratio.svelte";
|
||||
|
||||
export { Root, Root as AspectRatio };
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Avatar as AvatarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AvatarPrimitive.FallbackProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AvatarPrimitive.Fallback
|
||||
class={cn("flex h-full w-full items-center justify-center rounded-full bg-muted", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</AvatarPrimitive.Fallback>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Avatar as AvatarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AvatarPrimitive.ImageProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let src: $$Props["src"] = undefined;
|
||||
export let alt: $$Props["alt"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AvatarPrimitive.Image
|
||||
{src}
|
||||
{alt}
|
||||
class={cn("aspect-square h-full w-full", className)}
|
||||
{...$$restProps}
|
||||
/>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Avatar as AvatarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = AvatarPrimitive.Props;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let delayMs: $$Props["delayMs"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<AvatarPrimitive.Root
|
||||
{delayMs}
|
||||
class={cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</AvatarPrimitive.Root>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import Root from "./avatar.svelte";
|
||||
import Image from "./avatar-image.svelte";
|
||||
import Fallback from "./avatar-fallback.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Image,
|
||||
Fallback,
|
||||
//
|
||||
Root as Avatar,
|
||||
Image as AvatarImage,
|
||||
Fallback as AvatarFallback,
|
||||
};
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { type Variant, badgeVariants } from "./index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export let href: string | undefined = undefined;
|
||||
export let variant: Variant = "default";
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={href ? "a" : "span"}
|
||||
{href}
|
||||
class={cn(badgeVariants({ variant, className }))}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</svelte:element>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
export { default as Badge } from "./badge.svelte";
|
||||
|
||||
export const badgeVariants = tv({
|
||||
base: "inline-flex select-none items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
variants: {
|
||||
variant: {
|
||||
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
||||
secondary:
|
||||
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
destructive:
|
||||
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
||||
outline: "text-foreground",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
},
|
||||
});
|
||||
|
||||
export type Variant = VariantProps<typeof badgeVariants>["variant"];
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<script lang="ts">
|
||||
import Ellipsis from "lucide-svelte/icons/ellipsis";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLSpanElement> & {
|
||||
el?: HTMLSpanElement;
|
||||
};
|
||||
|
||||
export let el: $$Props["el"] = undefined;
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<span
|
||||
bind:this={el}
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
class={cn("flex h-9 w-9 items-center justify-center", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<Ellipsis class="h-4 w-4" />
|
||||
<span class="sr-only">More</span>
|
||||
</span>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLLiAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLLiAttributes & {
|
||||
el?: HTMLLIElement;
|
||||
};
|
||||
|
||||
export let el: $$Props["el"] = undefined;
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<li bind:this={el} class={cn("inline-flex items-center gap-1.5", className)}>
|
||||
<slot />
|
||||
</li>
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAnchorAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAnchorAttributes & {
|
||||
el?: HTMLAnchorElement;
|
||||
asChild?: boolean;
|
||||
};
|
||||
|
||||
export let href: $$Props["href"] = undefined;
|
||||
export let el: $$Props["el"] = undefined;
|
||||
export let asChild: $$Props["asChild"] = false;
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
|
||||
let attrs: Record<string, unknown>;
|
||||
|
||||
$: attrs = {
|
||||
class: cn("transition-colors hover:text-foreground", className),
|
||||
href,
|
||||
...$$restProps,
|
||||
};
|
||||
</script>
|
||||
|
||||
{#if asChild}
|
||||
<slot {attrs} />
|
||||
{:else}
|
||||
<a bind:this={el} {...attrs} {href}>
|
||||
<slot {attrs} />
|
||||
</a>
|
||||
{/if}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLOlAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLOlAttributes & {
|
||||
el?: HTMLOListElement;
|
||||
};
|
||||
|
||||
export let el: $$Props["el"] = undefined;
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ol
|
||||
bind:this={el}
|
||||
class={cn(
|
||||
"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</ol>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLSpanElement> & {
|
||||
el?: HTMLSpanElement;
|
||||
};
|
||||
|
||||
export let el: $$Props["el"] = undefined;
|
||||
export let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<span
|
||||
bind:this={el}
|
||||
role="link"
|
||||
aria-disabled="true"
|
||||
aria-current="page"
|
||||
class={cn("font-normal text-foreground", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</span>
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLLiAttributes } from "svelte/elements";
|
||||
import ChevronRight from "lucide-svelte/icons/chevron-right";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLLiAttributes & {
|
||||
el?: HTMLLIElement;
|
||||
};
|
||||
|
||||
export let el: $$Props["el"] = undefined;
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<li
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
class={cn("[&>svg]:size-3.5", className)}
|
||||
bind:this={el}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot>
|
||||
<ChevronRight />
|
||||
</slot>
|
||||
</li>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLElement> & {
|
||||
el?: HTMLElement;
|
||||
};
|
||||
|
||||
export let el: $$Props["el"] = undefined;
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<nav class={className} bind:this={el} aria-label="breadcrumb" {...$$restProps}>
|
||||
<slot />
|
||||
</nav>
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import Root from "./breadcrumb.svelte";
|
||||
import Ellipsis from "./breadcrumb-ellipsis.svelte";
|
||||
import Item from "./breadcrumb-item.svelte";
|
||||
import Separator from "./breadcrumb-separator.svelte";
|
||||
import Link from "./breadcrumb-link.svelte";
|
||||
import List from "./breadcrumb-list.svelte";
|
||||
import Page from "./breadcrumb-page.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
Ellipsis,
|
||||
Item,
|
||||
Separator,
|
||||
Link,
|
||||
List,
|
||||
Page,
|
||||
//
|
||||
Root as Breadcrumb,
|
||||
Ellipsis as BreadcrumbEllipsis,
|
||||
Item as BreadcrumbItem,
|
||||
Separator as BreadcrumbSeparator,
|
||||
Link as BreadcrumbLink,
|
||||
List as BreadcrumbList,
|
||||
Page as BreadcrumbPage,
|
||||
};
|
||||
|
|
@ -1,25 +1,74 @@
|
|||
<script lang="ts">
|
||||
import { Button as ButtonPrimitive } from "bits-ui";
|
||||
import { type Events, type Props, buttonVariants } from "./index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
<script lang="ts" module>
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
|
||||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
|
||||
type $$Props = Props;
|
||||
type $$Events = Events;
|
||||
export const buttonVariants = tv({
|
||||
base: "ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline:
|
||||
"border-input bg-background hover:bg-accent hover:text-accent-foreground border",
|
||||
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
});
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let variant: $$Props["variant"] = "default";
|
||||
export let size: $$Props["size"] = "default";
|
||||
export let builders: $$Props["builders"] = [];
|
||||
export { className as class };
|
||||
export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
|
||||
export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
|
||||
|
||||
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
||||
WithElementRef<HTMLAnchorAttributes> & {
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
};
|
||||
</script>
|
||||
|
||||
<ButtonPrimitive.Root
|
||||
{builders}
|
||||
class={cn(buttonVariants({ variant, size, className }))}
|
||||
type="button"
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
>
|
||||
<slot />
|
||||
</ButtonPrimitive.Root>
|
||||
<script lang="ts">
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
class: className,
|
||||
variant = "default",
|
||||
size = "default",
|
||||
ref = $bindable(null),
|
||||
href = undefined,
|
||||
type = "button",
|
||||
children,
|
||||
...restProps
|
||||
}: ButtonProps = $props();
|
||||
</script>
|
||||
|
||||
{#if href}
|
||||
<a
|
||||
bind:this={ref}
|
||||
class={cn(buttonVariants({ variant, size }), className)}
|
||||
{href}
|
||||
{...restProps}
|
||||
>
|
||||
{@render children?.()}
|
||||
</a>
|
||||
{:else}
|
||||
<button
|
||||
bind:this={ref}
|
||||
class={cn(buttonVariants({ variant, size }), className)}
|
||||
{type}
|
||||
{...restProps}
|
||||
>
|
||||
{@render children?.()}
|
||||
</button>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,17 @@
|
|||
import { type VariantProps, tv } from "tailwind-variants";
|
||||
import type { Button as ButtonPrimitive } from "bits-ui";
|
||||
import Root from "./button.svelte";
|
||||
|
||||
const buttonVariants = tv({
|
||||
base: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
||||
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
});
|
||||
|
||||
type Variant = VariantProps<typeof buttonVariants>["variant"];
|
||||
type Size = VariantProps<typeof buttonVariants>["size"];
|
||||
|
||||
type Props = ButtonPrimitive.Props & {
|
||||
variant?: Variant;
|
||||
size?: Size;
|
||||
};
|
||||
|
||||
type Events = ButtonPrimitive.Events;
|
||||
import Root, {
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
buttonVariants,
|
||||
} from "./button.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
type Props,
|
||||
type Events,
|
||||
type ButtonProps as Props,
|
||||
//
|
||||
Root as Button,
|
||||
type Props as ButtonProps,
|
||||
type Events as ButtonEvents,
|
||||
buttonVariants,
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.CellProps;
|
||||
|
||||
export let date: $$Props["date"];
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Cell
|
||||
{date}
|
||||
class={cn(
|
||||
"relative h-9 w-9 p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([data-selected])]:rounded-md [&:has([data-selected])]:bg-accent [&:has([data-selected][data-outside-month])]:bg-accent/50",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</CalendarPrimitive.Cell>
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { buttonVariants } from "$lib/components/ui/button/index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.DayProps;
|
||||
type $$Events = CalendarPrimitive.DayEvents;
|
||||
|
||||
export let date: $$Props["date"];
|
||||
export let month: $$Props["month"];
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Day
|
||||
on:click
|
||||
{date}
|
||||
{month}
|
||||
class={cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
"h-9 w-9 p-0 font-normal ",
|
||||
"[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground",
|
||||
// Selected
|
||||
"data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:opacity-100 data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground",
|
||||
// Disabled
|
||||
"data-[disabled]:text-muted-foreground data-[disabled]:opacity-50",
|
||||
// Unavailable
|
||||
"data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through",
|
||||
// Outside months
|
||||
"data-[outside-month]:pointer-events-none data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50 [&[data-outside-month][data-selected]]:bg-accent/50 [&[data-outside-month][data-selected]]:text-muted-foreground [&[data-outside-month][data-selected]]:opacity-30",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
let:selected
|
||||
let:disabled
|
||||
let:unavailable
|
||||
let:builder
|
||||
>
|
||||
<slot {selected} {disabled} {unavailable} {builder}>
|
||||
{date.day}
|
||||
</slot>
|
||||
</CalendarPrimitive.Day>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.GridBodyProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.GridBody class={cn(className)} {...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.GridBody>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.GridHeadProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.GridHead class={cn(className)} {...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.GridHead>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.GridRowProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.GridRow class={cn("flex", className)} {...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.GridRow>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.GridProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Grid class={cn("w-full border-collapse space-y-1", className)} {...$$restProps}>
|
||||
<slot />
|
||||
</CalendarPrimitive.Grid>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.HeadCellProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.HeadCell
|
||||
class={cn("w-9 rounded-md text-[0.8rem] font-normal text-muted-foreground", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</CalendarPrimitive.HeadCell>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.HeaderProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Header
|
||||
class={cn("relative flex w-full items-center justify-between pt-1", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</CalendarPrimitive.Header>
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.HeadingProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Heading
|
||||
let:headingValue
|
||||
class={cn("text-sm font-medium", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot {headingValue}>
|
||||
{headingValue}
|
||||
</slot>
|
||||
</CalendarPrimitive.Heading>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn("mt-4 flex flex-col space-y-4 sm:flex-row sm:space-x-4 sm:space-y-0", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import ChevronRight from "lucide-svelte/icons/chevron-right";
|
||||
import { buttonVariants } from "$lib/components/ui/button/index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.NextButtonProps;
|
||||
type $$Events = CalendarPrimitive.NextButtonEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.NextButton
|
||||
on:click
|
||||
class={cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
let:builder
|
||||
>
|
||||
<slot {builder}>
|
||||
<ChevronRight class="h-4 w-4" />
|
||||
</slot>
|
||||
</CalendarPrimitive.NextButton>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import ChevronLeft from "lucide-svelte/icons/chevron-left";
|
||||
import { buttonVariants } from "$lib/components/ui/button/index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.PrevButtonProps;
|
||||
type $$Events = CalendarPrimitive.PrevButtonEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.PrevButton
|
||||
on:click
|
||||
class={cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
let:builder
|
||||
>
|
||||
<slot {builder}>
|
||||
<ChevronLeft class="h-4 w-4" />
|
||||
</slot>
|
||||
</CalendarPrimitive.PrevButton>
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Calendar as CalendarPrimitive } from "bits-ui";
|
||||
import * as Calendar from "./index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CalendarPrimitive.Props;
|
||||
|
||||
type $$Events = CalendarPrimitive.Events;
|
||||
|
||||
export let value: $$Props["value"] = undefined;
|
||||
export let placeholder: $$Props["placeholder"] = undefined;
|
||||
export let weekdayFormat: $$Props["weekdayFormat"] = "short";
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CalendarPrimitive.Root
|
||||
bind:value
|
||||
bind:placeholder
|
||||
{weekdayFormat}
|
||||
class={cn("p-3", className)}
|
||||
{...$$restProps}
|
||||
on:keydown
|
||||
let:months
|
||||
let:weekdays
|
||||
>
|
||||
<Calendar.Header>
|
||||
<Calendar.PrevButton />
|
||||
<Calendar.Heading />
|
||||
<Calendar.NextButton />
|
||||
</Calendar.Header>
|
||||
<Calendar.Months>
|
||||
{#each months as month}
|
||||
<Calendar.Grid>
|
||||
<Calendar.GridHead>
|
||||
<Calendar.GridRow class="flex">
|
||||
{#each weekdays as weekday}
|
||||
<Calendar.HeadCell>
|
||||
{weekday.slice(0, 2)}
|
||||
</Calendar.HeadCell>
|
||||
{/each}
|
||||
</Calendar.GridRow>
|
||||
</Calendar.GridHead>
|
||||
<Calendar.GridBody>
|
||||
{#each month.weeks as weekDates}
|
||||
<Calendar.GridRow class="mt-2 w-full">
|
||||
{#each weekDates as date}
|
||||
<Calendar.Cell {date}>
|
||||
<Calendar.Day {date} month={month.value} />
|
||||
</Calendar.Cell>
|
||||
{/each}
|
||||
</Calendar.GridRow>
|
||||
{/each}
|
||||
</Calendar.GridBody>
|
||||
</Calendar.Grid>
|
||||
{/each}
|
||||
</Calendar.Months>
|
||||
</CalendarPrimitive.Root>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import Root from "./calendar.svelte";
|
||||
import Cell from "./calendar-cell.svelte";
|
||||
import Day from "./calendar-day.svelte";
|
||||
import Grid from "./calendar-grid.svelte";
|
||||
import Header from "./calendar-header.svelte";
|
||||
import Months from "./calendar-months.svelte";
|
||||
import GridRow from "./calendar-grid-row.svelte";
|
||||
import Heading from "./calendar-heading.svelte";
|
||||
import GridBody from "./calendar-grid-body.svelte";
|
||||
import GridHead from "./calendar-grid-head.svelte";
|
||||
import HeadCell from "./calendar-head-cell.svelte";
|
||||
import NextButton from "./calendar-next-button.svelte";
|
||||
import PrevButton from "./calendar-prev-button.svelte";
|
||||
|
||||
export {
|
||||
Day,
|
||||
Cell,
|
||||
Grid,
|
||||
Header,
|
||||
Months,
|
||||
GridRow,
|
||||
Heading,
|
||||
GridBody,
|
||||
GridHead,
|
||||
HeadCell,
|
||||
NextButton,
|
||||
PrevButton,
|
||||
//
|
||||
Root as Calendar,
|
||||
};
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
<script lang="ts">
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||
</script>
|
||||
|
||||
<div class={cn("p-6 pt-0", className)} {...$$restProps}>
|
||||
<slot />
|
||||
<div bind:this={ref} class={cn("p-6", className)} {...restProps}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
<script lang="ts">
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLParagraphElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLParagraphElement>> = $props();
|
||||
</script>
|
||||
|
||||
<p class={cn("text-sm text-muted-foreground", className)} {...$$restProps}>
|
||||
<slot />
|
||||
<p bind:this={ref} class={cn("text-muted-foreground text-sm", className)} {...restProps}>
|
||||
{@render children?.()}
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
<script lang="ts">
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||
</script>
|
||||
|
||||
<div class={cn("flex items-center p-6 pt-0", className)} {...$$restProps}>
|
||||
<slot />
|
||||
<div bind:this={ref} class={cn("flex items-center p-6 pt-0", className)} {...restProps}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
<script lang="ts">
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||
</script>
|
||||
|
||||
<div class={cn("flex flex-col space-y-1.5 p-6", className)} {...$$restProps}>
|
||||
<slot />
|
||||
<div bind:this={ref} class={cn("flex flex-col space-y-1.5 p-6 pb-0", className)} {...restProps}>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,25 @@
|
|||
<script lang="ts">
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import type { HeadingLevel } from "./index.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
|
||||
tag?: HeadingLevel;
|
||||
};
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let tag: $$Props["tag"] = "h3";
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
level = 3,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={tag}
|
||||
class={cn("text-lg font-semibold leading-none tracking-tight", className)}
|
||||
{...$$restProps}
|
||||
<div
|
||||
role="heading"
|
||||
aria-level={level}
|
||||
bind:this={ref}
|
||||
class={cn("text-2xl font-semibold leading-none tracking-tight", className)}
|
||||
{...restProps}
|
||||
>
|
||||
<slot />
|
||||
</svelte:element>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
<script lang="ts">
|
||||
import type { WithElementRef } from "bits-ui";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
|
||||
{...$$restProps}
|
||||
bind:this={ref}
|
||||
class={cn("bg-card text-card-foreground rounded-lg border shadow-sm", className)}
|
||||
{...restProps}
|
||||
>
|
||||
<slot />
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,5 +20,3 @@ export {
|
|||
Header as CardHeader,
|
||||
Title as CardTitle,
|
||||
};
|
||||
|
||||
export type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import emblaCarouselSvelte from "embla-carousel-svelte";
|
||||
import { getEmblaContext } from "./context.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
|
||||
const { orientation, options, plugins, onInit } = getEmblaContext("<Carousel.Content/>");
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="overflow-hidden"
|
||||
use:emblaCarouselSvelte={{
|
||||
options: {
|
||||
container: "[data-embla-container]",
|
||||
slides: "[data-embla-slide]",
|
||||
...$options,
|
||||
axis: $orientation === "horizontal" ? "x" : "y",
|
||||
},
|
||||
plugins: $plugins,
|
||||
}}
|
||||
on:emblaInit={onInit}
|
||||
>
|
||||
<div
|
||||
class={cn("flex", $orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col", className)}
|
||||
data-embla-container=""
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { getEmblaContext } from "./context.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
|
||||
const { orientation } = getEmblaContext("<Carousel.Item/>");
|
||||
</script>
|
||||
|
||||
<div
|
||||
role="group"
|
||||
aria-roledescription="slide"
|
||||
class={cn(
|
||||
"min-w-0 shrink-0 grow-0 basis-full",
|
||||
$orientation === "horizontal" ? "pl-4" : "pt-4",
|
||||
className
|
||||
)}
|
||||
data-embla-slide=""
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<script lang="ts">
|
||||
import ArrowRight from "lucide-svelte/icons/arrow-right";
|
||||
import type { VariantProps } from "tailwind-variants";
|
||||
import { getEmblaContext } from "./context.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import {
|
||||
Button,
|
||||
type Props,
|
||||
type buttonVariants,
|
||||
} from "$lib/components/ui/button/index.js";
|
||||
|
||||
type $$Props = Props;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
export let variant: VariantProps<typeof buttonVariants>["variant"] = "outline";
|
||||
export let size: VariantProps<typeof buttonVariants>["size"] = "icon";
|
||||
const { orientation, canScrollNext, scrollNext, handleKeyDown } =
|
||||
getEmblaContext("<Carousel.Next/>");
|
||||
</script>
|
||||
|
||||
<Button
|
||||
{variant}
|
||||
{size}
|
||||
class={cn(
|
||||
"absolute h-8 w-8 touch-manipulation rounded-full",
|
||||
$orientation === "horizontal"
|
||||
? "-right-12 top-1/2 -translate-y-1/2"
|
||||
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
||||
className
|
||||
)}
|
||||
disabled={!$canScrollNext}
|
||||
on:click={scrollNext}
|
||||
on:keydown={handleKeyDown}
|
||||
{...$$restProps}
|
||||
>
|
||||
<ArrowRight class="h-4 w-4" />
|
||||
<span class="sr-only">Next slide</span>
|
||||
</Button>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<script lang="ts">
|
||||
import ArrowLeft from "lucide-svelte/icons/arrow-left";
|
||||
import type { VariantProps } from "tailwind-variants";
|
||||
import { getEmblaContext } from "./context.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
import {
|
||||
Button,
|
||||
type Props,
|
||||
type buttonVariants,
|
||||
} from "$lib/components/ui/button/index.js";
|
||||
|
||||
type $$Props = Props;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
export let variant: VariantProps<typeof buttonVariants>["variant"] = "outline";
|
||||
export let size: VariantProps<typeof buttonVariants>["size"] = "icon";
|
||||
|
||||
const { orientation, canScrollPrev, scrollPrev, handleKeyDown } =
|
||||
getEmblaContext("<Carousel.Previous/>");
|
||||
</script>
|
||||
|
||||
<Button
|
||||
{variant}
|
||||
{size}
|
||||
class={cn(
|
||||
"absolute h-8 w-8 touch-manipulation rounded-full",
|
||||
$orientation === "horizontal"
|
||||
? "-left-12 top-1/2 -translate-y-1/2"
|
||||
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
||||
className
|
||||
)}
|
||||
disabled={!$canScrollPrev}
|
||||
on:click={scrollPrev}
|
||||
on:keydown={handleKeyDown}
|
||||
{...$$restProps}
|
||||
>
|
||||
<ArrowLeft class="h-4 w-4" />
|
||||
<span class="sr-only">Previous slide</span>
|
||||
</Button>
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { writable } from "svelte/store";
|
||||
import { onDestroy } from "svelte";
|
||||
import { type CarouselAPI, type CarouselProps, setEmblaContext } from "./context.js";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CarouselProps;
|
||||
|
||||
export let opts = {};
|
||||
export let plugins: NonNullable<$$Props["plugins"]> = [];
|
||||
export let api: $$Props["api"] = undefined;
|
||||
export let orientation: NonNullable<$$Props["orientation"]> = "horizontal";
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
|
||||
const apiStore = writable<CarouselAPI | undefined>(undefined);
|
||||
const orientationStore = writable(orientation);
|
||||
const canScrollPrev = writable(false);
|
||||
const canScrollNext = writable(false);
|
||||
const optionsStore = writable(opts);
|
||||
const pluginStore = writable(plugins);
|
||||
const scrollSnapsStore = writable<number[]>([]);
|
||||
const selectedIndexStore = writable(0);
|
||||
|
||||
$: orientationStore.set(orientation);
|
||||
$: pluginStore.set(plugins);
|
||||
$: optionsStore.set(opts);
|
||||
|
||||
function scrollPrev() {
|
||||
api?.scrollPrev();
|
||||
}
|
||||
function scrollNext() {
|
||||
api?.scrollNext();
|
||||
}
|
||||
function scrollTo(index: number, jump?: boolean) {
|
||||
api?.scrollTo(index, jump);
|
||||
}
|
||||
|
||||
function onSelect(api: CarouselAPI) {
|
||||
if (!api) return;
|
||||
canScrollPrev.set(api.canScrollPrev());
|
||||
canScrollNext.set(api.canScrollNext());
|
||||
}
|
||||
|
||||
$: if (api) {
|
||||
onSelect(api);
|
||||
api.on("select", onSelect);
|
||||
api.on("reInit", onSelect);
|
||||
}
|
||||
|
||||
function handleKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "ArrowLeft") {
|
||||
e.preventDefault();
|
||||
scrollPrev();
|
||||
} else if (e.key === "ArrowRight") {
|
||||
e.preventDefault();
|
||||
scrollNext();
|
||||
}
|
||||
}
|
||||
|
||||
setEmblaContext({
|
||||
api: apiStore,
|
||||
scrollPrev,
|
||||
scrollNext,
|
||||
orientation: orientationStore,
|
||||
canScrollNext,
|
||||
canScrollPrev,
|
||||
handleKeyDown,
|
||||
options: optionsStore,
|
||||
plugins: pluginStore,
|
||||
onInit,
|
||||
scrollSnaps: scrollSnapsStore,
|
||||
selectedIndex: selectedIndexStore,
|
||||
scrollTo,
|
||||
});
|
||||
|
||||
function onInit(event: CustomEvent<CarouselAPI>) {
|
||||
api = event.detail;
|
||||
apiStore.set(api);
|
||||
scrollSnapsStore.set(api.scrollSnapList());
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
api?.off("select", onSelect);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn("relative", className)}
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
role="region"
|
||||
aria-roledescription="carousel"
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
import type { EmblaCarouselSvelteType } from "embla-carousel-svelte";
|
||||
import type emblaCarouselSvelte from "embla-carousel-svelte";
|
||||
import { getContext, hasContext, setContext } from "svelte";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import type { Readable, Writable } from "svelte/store";
|
||||
|
||||
export type CarouselAPI =
|
||||
NonNullable<NonNullable<EmblaCarouselSvelteType["$$_attributes"]>["on:emblaInit"]> extends (
|
||||
evt: CustomEvent<infer CarouselAPI>
|
||||
) => void
|
||||
? CarouselAPI
|
||||
: never;
|
||||
|
||||
type EmblaCarouselConfig = NonNullable<Parameters<typeof emblaCarouselSvelte>[1]>;
|
||||
|
||||
export type CarouselOptions = EmblaCarouselConfig["options"];
|
||||
export type CarouselPlugins = EmblaCarouselConfig["plugins"];
|
||||
|
||||
////
|
||||
|
||||
export type CarouselProps = {
|
||||
opts?: CarouselOptions;
|
||||
plugins?: CarouselPlugins;
|
||||
api?: CarouselAPI;
|
||||
orientation?: "horizontal" | "vertical";
|
||||
} & HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
const EMBLA_CAROUSEL_CONTEXT = Symbol("EMBLA_CAROUSEL_CONTEXT");
|
||||
|
||||
type EmblaContext = {
|
||||
api: Writable<CarouselAPI | undefined>;
|
||||
orientation: Writable<"horizontal" | "vertical">;
|
||||
scrollNext: () => void;
|
||||
scrollPrev: () => void;
|
||||
canScrollNext: Readable<boolean>;
|
||||
canScrollPrev: Readable<boolean>;
|
||||
handleKeyDown: (e: KeyboardEvent) => void;
|
||||
options: Writable<CarouselOptions>;
|
||||
plugins: Writable<CarouselPlugins>;
|
||||
onInit: (e: CustomEvent<CarouselAPI>) => void;
|
||||
scrollTo: (index: number, jump?: boolean) => void;
|
||||
scrollSnaps: Readable<number[]>;
|
||||
selectedIndex: Readable<number>;
|
||||
};
|
||||
|
||||
export function setEmblaContext(config: EmblaContext): EmblaContext {
|
||||
setContext(EMBLA_CAROUSEL_CONTEXT, config);
|
||||
return config;
|
||||
}
|
||||
|
||||
export function getEmblaContext(name = "This component") {
|
||||
if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) {
|
||||
throw new Error(`${name} must be used within a <Carousel.Root> component`);
|
||||
}
|
||||
return getContext<ReturnType<typeof setEmblaContext>>(EMBLA_CAROUSEL_CONTEXT);
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
export { default as Root } from "./carousel.svelte";
|
||||
export { default as Content } from "./carousel-content.svelte";
|
||||
export { default as Item } from "./carousel-item.svelte";
|
||||
export { default as Previous } from "./carousel-previous.svelte";
|
||||
export { default as Next } from "./carousel-next.svelte";
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Checkbox as CheckboxPrimitive } from "bits-ui";
|
||||
import Check from "lucide-svelte/icons/check";
|
||||
import Minus from "lucide-svelte/icons/minus";
|
||||
import { cn } from "$lib/utils/ui.js";
|
||||
|
||||
type $$Props = CheckboxPrimitive.Props;
|
||||
type $$Events = CheckboxPrimitive.Events;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let checked: $$Props["checked"] = false;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CheckboxPrimitive.Root
|
||||
class={cn(
|
||||
"peer box-content h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[disabled=true]:cursor-not-allowed data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:opacity-50",
|
||||
className
|
||||
)}
|
||||
bind:checked
|
||||
{...$$restProps}
|
||||
on:click
|
||||
>
|
||||
<CheckboxPrimitive.Indicator
|
||||
class={cn("flex h-4 w-4 items-center justify-center text-current")}
|
||||
let:isChecked
|
||||
let:isIndeterminate
|
||||
>
|
||||
{#if isChecked}
|
||||
<Check class="h-3.5 w-3.5" />
|
||||
{:else if isIndeterminate}
|
||||
<Minus class="h-3.5 w-3.5" />
|
||||
{/if}
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import Root from "./checkbox.svelte";
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Checkbox,
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue