├── .github
└── workflows
│ └── tests.yml
├── .gitignore
├── .prettierrc.js
├── .storybook
├── main.js
└── preview.js
├── LICENSE
├── README.md
├── babel.config.js
├── eslint.config.js
├── jest
├── config.js
├── setup.js
├── setupForEach.js
└── testUtilities
│ ├── index.js
│ ├── renderHookWithProviders.js
│ └── renderWithProviders.js
├── jsconfig.json
├── package.json
├── src
├── __mocks__
│ └── filemock.js
├── components
│ ├── animation
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── makeAnimations.js
│ │ └── makeAnimations.test.js
│ ├── button
│ │ ├── README.md
│ │ ├── __snapshots__
│ │ │ └── button.test.js.snap
│ │ ├── button.js
│ │ ├── button.stories.js
│ │ ├── button.test.js
│ │ ├── buttonGroup.js
│ │ ├── constants.js
│ │ ├── iconButton.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ └── styled.js
│ ├── checkbox
│ │ ├── README.md
│ │ ├── checkbox.js
│ │ ├── checkbox.mock.js
│ │ ├── checkbox.stories.js
│ │ ├── checkbox.test.js
│ │ ├── hooks.js
│ │ ├── index.js
│ │ └── styled.js
│ ├── collapsible
│ │ ├── README.md
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ └── index.test.js
│ ├── confirmation-dialog
│ │ ├── confirmation-dialog.d.ts
│ │ ├── confirmation-dialog.js
│ │ ├── confirmation-dialog.stories.js
│ │ ├── confirmation-dialog.test.js
│ │ ├── index.js
│ │ └── styled.js
│ ├── drops
│ │ ├── container.js
│ │ ├── drop
│ │ │ ├── README.md
│ │ │ ├── container.js
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.stories.js
│ │ │ ├── index.test.js
│ │ │ ├── useDimensionChange.js
│ │ │ └── useMakeUpdatePosition.js
│ │ ├── menu
│ │ │ ├── README.md
│ │ │ ├── dropdown.js
│ │ │ ├── dropdownItem.js
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.stories.js
│ │ │ ├── index.test.js
│ │ │ └── menuButton.js
│ │ ├── mixins
│ │ │ ├── dropAlignMap.js
│ │ │ ├── getAncestors.js
│ │ │ ├── index.d.ts
│ │ │ ├── isAncestor.js
│ │ │ ├── useClonedChildren.js
│ │ │ └── useDescribedId.js
│ │ ├── popover
│ │ │ ├── README.md
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.stories.js
│ │ │ └── index.test.js
│ │ └── tooltip
│ │ │ ├── README.md
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.stories.js
│ │ │ └── index.test.js
│ ├── icon
│ │ ├── README.md
│ │ ├── assets
│ │ │ ├── D.svg
│ │ │ ├── I.svg
│ │ │ ├── L.svg
│ │ │ ├── N.svg
│ │ │ ├── add_node.svg
│ │ │ ├── add_user.svg
│ │ │ ├── aggregation_avg.svg
│ │ │ ├── aggregation_max.svg
│ │ │ ├── aggregation_med.svg
│ │ │ ├── aggregation_min.svg
│ │ │ ├── aggregation_sum.svg
│ │ │ ├── aggregation_sum_abs.svg
│ │ │ ├── alarm.svg
│ │ │ ├── alarmFilled.svg
│ │ │ ├── alarm_bell.svg
│ │ │ ├── alarm_c.svg
│ │ │ ├── alarm_cw.svg
│ │ │ ├── alarm_off.svg
│ │ │ ├── alarm_w.svg
│ │ │ ├── alarms_new.svg
│ │ │ ├── anomalies_brain.svg
│ │ │ ├── anomalies_lens.svg
│ │ │ ├── anomaly_badge.svg
│ │ │ ├── applications_hollow.svg
│ │ │ ├── applications_solid.svg
│ │ │ ├── area_chart.svg
│ │ │ ├── around_clock.svg
│ │ │ ├── arrow-s_down.svg
│ │ │ ├── arrow-s_left.svg
│ │ │ ├── arrow_down.svg
│ │ │ ├── arrow_left.svg
│ │ │ ├── arrow_w_line_left.svg
│ │ │ ├── arrow_w_line_right.svg
│ │ │ ├── arrows_vertical.svg
│ │ │ ├── auth.svg
│ │ │ ├── bar_chart.svg
│ │ │ ├── bookmark.svg
│ │ │ ├── bullet_one.svg
│ │ │ ├── bullet_three.svg
│ │ │ ├── bullet_two.svg
│ │ │ ├── calendar_full.svg
│ │ │ ├── calendar_full_press.svg
│ │ │ ├── chart_added.svg
│ │ │ ├── chart_bars.svg
│ │ │ ├── chart_circle.svg
│ │ │ ├── chart_gauge.svg
│ │ │ ├── chart_pie.svg
│ │ │ ├── charts.svg
│ │ │ ├── charts_view.svg
│ │ │ ├── check.svg
│ │ │ ├── checkmark.svg
│ │ │ ├── checkmark_partial_s.svg
│ │ │ ├── checkmark_s.svg
│ │ │ ├── chevron_double.svg
│ │ │ ├── chevron_down.svg
│ │ │ ├── chevron_down_thin.svg
│ │ │ ├── chevron_expand.svg
│ │ │ ├── chevron_left.svg
│ │ │ ├── chevron_left_small.svg
│ │ │ ├── chevron_left_start.svg
│ │ │ ├── chevron_right.svg
│ │ │ ├── chevron_right_end.svg
│ │ │ ├── chevron_right_s.svg
│ │ │ ├── chevron_right_small.svg
│ │ │ ├── chevron_up_thin.svg
│ │ │ ├── class_error.svg
│ │ │ ├── class_latency.svg
│ │ │ ├── class_utilization.svg
│ │ │ ├── class_workload.svg
│ │ │ ├── clock_5_min.svg
│ │ │ ├── clock_5_min_press.svg
│ │ │ ├── clock_hollow.svg
│ │ │ ├── close_circle.svg
│ │ │ ├── cluster.svg
│ │ │ ├── cluster_spaces.svg
│ │ │ ├── code.svg
│ │ │ ├── collapse.svg
│ │ │ ├── collect.svg
│ │ │ ├── community.svg
│ │ │ ├── connection_to_cloud.svg
│ │ │ ├── connectivity_status_live.svg
│ │ │ ├── connectivity_status_offline.svg
│ │ │ ├── connectivity_status_stale.svg
│ │ │ ├── container.svg
│ │ │ ├── controller_kind.svg
│ │ │ ├── controller_name.svg
│ │ │ ├── copy.svg
│ │ │ ├── correlation.svg
│ │ │ ├── correlation_inv.svg
│ │ │ ├── correlations.svg
│ │ │ ├── cpu.svg
│ │ │ ├── cross_s.svg
│ │ │ ├── dashboard.svg
│ │ │ ├── dashboard_add.svg
│ │ │ ├── dashboard_add_chart.svg
│ │ │ ├── dashboards.svg
│ │ │ ├── data_retention.svg
│ │ │ ├── database.svg
│ │ │ ├── difference.svg
│ │ │ ├── discovered_config.svg
│ │ │ ├── disk.svg
│ │ │ ├── documentation.svg
│ │ │ ├── dot.svg
│ │ │ ├── dots_2x3.svg
│ │ │ ├── download.svg
│ │ │ ├── drag_horizontal.svg
│ │ │ ├── drag_vertical.svg
│ │ │ ├── dynamic_config.svg
│ │ │ ├── edit.svg
│ │ │ ├── error.svg
│ │ │ ├── exclamation.svg
│ │ │ ├── expand.svg
│ │ │ ├── favorites.svg
│ │ │ ├── feed.svg
│ │ │ ├── filter.svg
│ │ │ ├── filterList.svg
│ │ │ ├── firewall_solid.svg
│ │ │ ├── force_play.svg
│ │ │ ├── force_play_outline.svg
│ │ │ ├── full_screen.svg
│ │ │ ├── fullscreen.svg
│ │ │ ├── functions.svg
│ │ │ ├── gear.svg
│ │ │ ├── gift_box.svg
│ │ │ ├── github.svg
│ │ │ ├── go_to_node.svg
│ │ │ ├── google.svg
│ │ │ ├── grid.svg
│ │ │ ├── group_by.svg
│ │ │ ├── h1.svg
│ │ │ ├── h2.svg
│ │ │ ├── hamburger.svg
│ │ │ ├── heart.svg
│ │ │ ├── heart_broken.svg
│ │ │ ├── heart_hollow.svg
│ │ │ ├── heatmap_chart.svg
│ │ │ ├── help.svg
│ │ │ ├── hide.svg
│ │ │ ├── highlight_area.svg
│ │ │ ├── holder.svg
│ │ │ ├── importExport.svg
│ │ │ ├── incident_manager.svg
│ │ │ ├── information.svg
│ │ │ ├── information_press.svg
│ │ │ ├── insights.svg
│ │ │ ├── integrations.svg
│ │ │ ├── integrations
│ │ │ │ ├── aws_sns.svg
│ │ │ │ ├── aws_sns_colored.svg
│ │ │ │ ├── discord.svg
│ │ │ │ ├── discord_colored.svg
│ │ │ │ ├── email.svg
│ │ │ │ ├── email_colored.svg
│ │ │ │ ├── ilert.svg
│ │ │ │ ├── ilert_colored.svg
│ │ │ │ ├── mattermost.svg
│ │ │ │ ├── mattermost_colored.svg
│ │ │ │ ├── mobile_app_colored.svg
│ │ │ │ ├── opsgenie.svg
│ │ │ │ ├── opsgenie_colored.svg
│ │ │ │ ├── pagerduty.svg
│ │ │ │ ├── pagerduty_colored.svg
│ │ │ │ ├── push_notifications.svg
│ │ │ │ ├── rocketChat.svg
│ │ │ │ ├── rocketChat_colored.svg
│ │ │ │ ├── slack.svg
│ │ │ │ ├── slack_colored.svg
│ │ │ │ ├── smseagle.svg
│ │ │ │ ├── smseagle_colored.svg
│ │ │ │ ├── splunk-black.svg
│ │ │ │ ├── teams.svg
│ │ │ │ ├── teams_colored.svg
│ │ │ │ ├── telegram.svg
│ │ │ │ ├── telegram_colored.svg
│ │ │ │ ├── victorOps.svg
│ │ │ │ ├── victorOps_colored.svg
│ │ │ │ ├── webhook.svg
│ │ │ │ └── webhook_colored.svg
│ │ │ ├── internal_config.svg
│ │ │ ├── ipNetworking.svg
│ │ │ ├── ipNetworkingPress.svg
│ │ │ ├── last_week.svg
│ │ │ ├── line_chart.svg
│ │ │ ├── line_chart2.svg
│ │ │ ├── list.svg
│ │ │ ├── loading.svg
│ │ │ ├── logo_s.svg
│ │ │ ├── logs.svg
│ │ │ ├── long_arrow_up.svg
│ │ │ ├── magnify.svg
│ │ │ ├── metrics.svg
│ │ │ ├── metrics_explorer.svg
│ │ │ ├── minimize_s.svg
│ │ │ ├── misc_select.svg
│ │ │ ├── mobile_push_notifications.svg
│ │ │ ├── mobile_push_notifications_hollow.svg
│ │ │ ├── monitoring.svg
│ │ │ ├── more.svg
│ │ │ ├── nav_arrow_goto.svg
│ │ │ ├── nav_dots.svg
│ │ │ ├── nav_left.svg
│ │ │ ├── nav_right.svg
│ │ │ ├── netdata-press.svg
│ │ │ ├── netdata.svg
│ │ │ ├── netdataAssistant.svg
│ │ │ ├── networking_stack.svg
│ │ │ ├── node.svg
│ │ │ ├── node_child.svg
│ │ │ ├── node_default_l.svg
│ │ │ ├── node_hollow.svg
│ │ │ ├── node_import_export.svg
│ │ │ ├── node_notification_l.svg
│ │ │ ├── node_parent.svg
│ │ │ ├── node_selected_l.svg
│ │ │ ├── nodes.svg
│ │ │ ├── nodes_hollow.svg
│ │ │ ├── nodes_update.svg
│ │ │ ├── none_selected.svg
│ │ │ ├── notification.svg
│ │ │ ├── notification_shortcut_disabled.svg
│ │ │ ├── notification_shortcut_enabled.svg
│ │ │ ├── notification_trigger.svg
│ │ │ ├── okta.svg
│ │ │ ├── openid.svg
│ │ │ ├── os
│ │ │ │ ├── alpine_linux.svg
│ │ │ │ ├── amazon_linux.svg
│ │ │ │ ├── arch_linux.svg
│ │ │ │ ├── celarOS.svg
│ │ │ │ ├── centos.svg
│ │ │ │ ├── centos_colored.svg
│ │ │ │ ├── coreOS.svg
│ │ │ │ ├── debian.svg
│ │ │ │ ├── debian_colored.svg
│ │ │ │ ├── fedora.svg
│ │ │ │ ├── freeBSD.svg
│ │ │ │ ├── gentoo.svg
│ │ │ │ ├── linux.svg
│ │ │ │ ├── linux_colored.svg
│ │ │ │ ├── linux_manjaro.svg
│ │ │ │ ├── linux_mint.svg
│ │ │ │ ├── macOSX.svg
│ │ │ │ ├── oracle.svg
│ │ │ │ ├── oracle_colored.svg
│ │ │ │ ├── os.svg
│ │ │ │ ├── os_press.svg
│ │ │ │ ├── raspbian.svg
│ │ │ │ ├── red_hat.svg
│ │ │ │ ├── suse_linux.svg
│ │ │ │ ├── ubuntu.svg
│ │ │ │ ├── ubuntu_colored.svg
│ │ │ │ └── windows.svg
│ │ │ ├── padlock.svg
│ │ │ ├── pan.svg
│ │ │ ├── pan_tool.svg
│ │ │ ├── pause_outline.svg
│ │ │ ├── pause_solid.svg
│ │ │ ├── pencil_outline.svg
│ │ │ ├── pencil_solid.svg
│ │ │ ├── pie_chart_skeleton.svg
│ │ │ ├── pin.svg
│ │ │ ├── pin_element.svg
│ │ │ ├── play_outline.svg
│ │ │ ├── play_solid.svg
│ │ │ ├── plugins.svg
│ │ │ ├── plus.svg
│ │ │ ├── plus_mini_s.svg
│ │ │ ├── pod.svg
│ │ │ ├── pricing.svg
│ │ │ ├── print.svg
│ │ │ ├── privacy.svg
│ │ │ ├── qr_code.svg
│ │ │ ├── qualityOfService_solid.svg
│ │ │ ├── question.svg
│ │ │ ├── questionFilled.svg
│ │ │ ├── ram.svg
│ │ │ ├── rearrange.svg
│ │ │ ├── reduce_size.svg
│ │ │ ├── refresh.svg
│ │ │ ├── reload.svg
│ │ │ ├── reload2.svg
│ │ │ ├── remove_node.svg
│ │ │ ├── resize_handler.svg
│ │ │ ├── rocket.svg
│ │ │ ├── room.svg
│ │ │ ├── room_home.svg
│ │ │ ├── room_new.svg
│ │ │ ├── room_overview.svg
│ │ │ ├── sad.svg
│ │ │ ├── save.svg
│ │ │ ├── save2.svg
│ │ │ ├── scheduled.svg
│ │ │ ├── search.svg
│ │ │ ├── search_press.svg
│ │ │ ├── search_s.svg
│ │ │ ├── select.svg
│ │ │ ├── selected_area.svg
│ │ │ ├── services
│ │ │ │ ├── alarm.svg
│ │ │ │ ├── apache.svg
│ │ │ │ ├── apache_tomcat.svg
│ │ │ │ ├── asterisk.svg
│ │ │ │ ├── beanstalk.svg
│ │ │ │ ├── bind.svg
│ │ │ │ ├── containerTech.svg
│ │ │ │ ├── coreDNS.svg
│ │ │ │ ├── couchDB.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── dns.svg
│ │ │ │ ├── dnsmasq.svg
│ │ │ │ ├── docker_hub.svg
│ │ │ │ ├── docker_hub_press.svg
│ │ │ │ ├── dotnet.svg
│ │ │ │ ├── eBPF.svg
│ │ │ │ ├── elasticSearch.svg
│ │ │ │ ├── example.svg
│ │ │ │ ├── freeNAS.svg
│ │ │ │ ├── haProxy.svg
│ │ │ │ ├── httpCheck.svg
│ │ │ │ ├── iceCast.svg
│ │ │ │ ├── influxDB.svg
│ │ │ │ ├── ipfs.svg
│ │ │ │ ├── ipvs.svg
│ │ │ │ ├── kubernetes.svg
│ │ │ │ ├── lighthttpd.svg
│ │ │ │ ├── lighthttpd2.svg
│ │ │ │ ├── liteSpeed.svg
│ │ │ │ ├── lxc.svg
│ │ │ │ ├── mariaDB.svg
│ │ │ │ ├── memCached.svg
│ │ │ │ ├── mongoDB.svg
│ │ │ │ ├── mySQL.svg
│ │ │ │ ├── mySQL_press.svg
│ │ │ │ ├── nginx.svg
│ │ │ │ ├── nginx_local.svg
│ │ │ │ ├── nginx_plus.svg
│ │ │ │ ├── ntpd.svg
│ │ │ │ ├── ntpd_press.svg
│ │ │ │ ├── nvidia.svg
│ │ │ │ ├── openStack.svg
│ │ │ │ ├── openWrt.svg
│ │ │ │ ├── pan.svg
│ │ │ │ ├── pandas.svg
│ │ │ │ ├── percona.svg
│ │ │ │ ├── pfSense.svg
│ │ │ │ ├── php_fpm.svg
│ │ │ │ ├── postgreSQL.svg
│ │ │ │ ├── prometheus.svg
│ │ │ │ ├── proxySQL.svg
│ │ │ │ ├── rabbitMQ.svg
│ │ │ │ ├── random.svg
│ │ │ │ ├── redis.svg
│ │ │ │ ├── rethinkDB.svg
│ │ │ │ ├── retroShare.svg
│ │ │ │ ├── selected_area.svg
│ │ │ │ ├── sendgrid.svg
│ │ │ │ ├── services.svg
│ │ │ │ ├── smartdlog.svg
│ │ │ │ ├── solr.svg
│ │ │ │ ├── squid.svg
│ │ │ │ ├── summary_statistic.svg
│ │ │ │ ├── systemd.svg
│ │ │ │ ├── traefik.svg
│ │ │ │ ├── varnish.svg
│ │ │ │ ├── webLog.svg
│ │ │ │ ├── webLog_nginx.svg
│ │ │ │ ├── x509_check.svg
│ │ │ │ └── xen.svg
│ │ │ ├── settings.svg
│ │ │ ├── settings_h.svg
│ │ │ ├── share.svg
│ │ │ ├── sign_in.svg
│ │ │ ├── sort_ascending.svg
│ │ │ ├── sort_descending.svg
│ │ │ ├── sort_indicator.svg
│ │ │ ├── sorting_asc.svg
│ │ │ ├── sorting_desc.svg
│ │ │ ├── sorting_vertical.svg
│ │ │ ├── space.svg
│ │ │ ├── space_new.svg
│ │ │ ├── spaces_v2.svg
│ │ │ ├── stacked_bar_chart.svg
│ │ │ ├── stacked_chart.svg
│ │ │ ├── stock_config.svg
│ │ │ ├── switch_off.svg
│ │ │ ├── system_overview.svg
│ │ │ ├── system_overview_press.svg
│ │ │ ├── text_add.svg
│ │ │ ├── thumb_down.svg
│ │ │ ├── thumb_up.svg
│ │ │ ├── tiny_buttons.svg
│ │ │ ├── top.svg
│ │ │ ├── training.svg
│ │ │ ├── trashcan.svg
│ │ │ ├── triangle.svg
│ │ │ ├── triangle_down.svg
│ │ │ ├── universe.svg
│ │ │ ├── unknownError.svg
│ │ │ ├── unreachable.svg
│ │ │ ├── unreachableNode.svg
│ │ │ ├── update.svg
│ │ │ ├── update_pending.svg
│ │ │ ├── upload.svg
│ │ │ ├── user.svg
│ │ │ ├── user_config.svg
│ │ │ ├── user_press.svg
│ │ │ ├── users.svg
│ │ │ ├── value.svg
│ │ │ ├── view_list.svg
│ │ │ ├── views
│ │ │ │ ├── single_node_view.svg
│ │ │ │ └── single_node_view_press.svg
│ │ │ ├── virtualization.svg
│ │ │ ├── warning.svg
│ │ │ ├── warning_triangle.svg
│ │ │ ├── warning_triangle_hollow.svg
│ │ │ ├── weights_compare.svg
│ │ │ ├── weights_drill_down.svg
│ │ │ ├── x.svg
│ │ │ ├── zoom_in.svg
│ │ │ ├── zoom_out.svg
│ │ │ └── zoom_reset.svg
│ │ ├── components
│ │ │ ├── index.js
│ │ │ └── loader.js
│ │ ├── icon.js
│ │ ├── icon.stories.js
│ │ ├── iconsList.js
│ │ ├── iconsList.stories.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ └── styled.js
│ ├── input
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── input.d.ts
│ │ ├── input.js
│ │ ├── input.mock.js
│ │ ├── input.stories.js
│ │ ├── input.test.js
│ │ ├── multiRange
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.stories.js
│ │ │ ├── index.test.js
│ │ │ └── styled.js
│ │ ├── range
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── range.stories.js
│ │ │ ├── range.test.js
│ │ │ └── styled.js
│ │ ├── styled.js
│ │ ├── use-focused-state.js
│ │ ├── use-input-value.d.ts
│ │ ├── use-input-value.js
│ │ ├── use-touched-state.d.ts
│ │ └── use-touched-state.js
│ ├── intersection
│ │ ├── README.md
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ └── index.test.js
│ ├── modal
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ └── index.test.js
│ ├── pill
│ │ ├── alertMastercard.d.ts
│ │ ├── alertMastercard.js
│ │ ├── alertMastercard.test.js
│ │ ├── icon.d.ts
│ │ ├── icon.js
│ │ ├── icon.test.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ ├── mastercard.d.ts
│ │ ├── mastercard.js
│ │ ├── mastercard.test.js
│ │ ├── mastercardPill.d.ts
│ │ ├── mastercardPill.js
│ │ ├── mastercardPill.test.js
│ │ ├── mixins
│ │ │ ├── background.js
│ │ │ ├── colors.js
│ │ │ ├── height.js
│ │ │ ├── padding.js
│ │ │ └── width.js
│ │ ├── pill.test.js
│ │ └── styled.js
│ ├── progressBar
│ │ ├── README.md
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ └── index.test.js
│ ├── radio-button
│ │ ├── README.md
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.storiess.js
│ │ ├── index.test.js
│ │ ├── mixins
│ │ │ ├── disabled.js
│ │ │ └── disabled.test.js
│ │ └── styled.js
│ ├── search
│ │ └── index.js
│ ├── select
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ └── index.stories.js
│ ├── sidebar
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── portal-sidebar.test.js
│ │ ├── portaled-sidebar.d.ts
│ │ ├── portaled-sidebar.js
│ │ ├── sidebar.js
│ │ ├── sidebar.storiess.js
│ │ ├── sidebar.test.js
│ │ └── styled.js
│ ├── table
│ │ ├── body
│ │ │ ├── header
│ │ │ │ ├── cell.js
│ │ │ │ ├── filter
│ │ │ │ │ ├── comparison.js
│ │ │ │ │ ├── dropdown.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── search.js
│ │ │ │ │ └── select.js
│ │ │ │ ├── index.js
│ │ │ │ ├── info.js
│ │ │ │ ├── resizeHandler.js
│ │ │ │ └── sorting.js
│ │ │ ├── index.js
│ │ │ └── row.js
│ │ ├── components
│ │ │ ├── action.js
│ │ │ └── pagination.js
│ │ ├── header
│ │ │ ├── actions
│ │ │ │ ├── action.js
│ │ │ │ ├── columnVisibility
│ │ │ │ │ ├── columnsMenu.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── index.js
│ │ │ │ └── useActions.js
│ │ │ ├── groupBy.js
│ │ │ └── index.js
│ │ ├── helpers
│ │ │ ├── downloadCsv.js
│ │ │ └── filterFns.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── provider.js
│ │ ├── table.js
│ │ ├── table.storiess.js
│ │ ├── useColumns
│ │ │ ├── index.js
│ │ │ ├── useRowActions.js
│ │ │ └── useRowSelection.js
│ │ ├── useExpanding.js
│ │ ├── useGrouping.js
│ │ ├── usePaginating.js
│ │ ├── usePinning.js
│ │ ├── useSearching.js
│ │ ├── useSelecting.js
│ │ ├── useSizing.js
│ │ ├── useSorting.js
│ │ └── useVisibility.js
│ ├── tabs
│ │ ├── README.md
│ │ ├── __snapshots__
│ │ │ └── tabs.test.js.snap
│ │ ├── index.js
│ │ ├── styled.js
│ │ ├── tab.d.ts
│ │ ├── tab.js
│ │ ├── tabs-hooks.js
│ │ ├── tabs.d.ts
│ │ ├── tabs.js
│ │ ├── tabs.storiess.js
│ │ └── tabs.test.js
│ ├── templates
│ │ ├── box
│ │ │ ├── README.md
│ │ │ ├── box.js
│ │ │ ├── box.test.js
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ └── index.stories.js
│ │ ├── flex
│ │ │ ├── README.md
│ │ │ ├── flex.js
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.stories.js
│ │ │ └── index.test.js
│ │ ├── layer
│ │ │ ├── README.md
│ │ │ ├── backdropContainer.js
│ │ │ ├── container.js
│ │ │ ├── index.d.ts
│ │ │ ├── index.js
│ │ │ ├── index.stories.js
│ │ │ ├── index.test.js
│ │ │ └── mixins
│ │ │ │ ├── backdropBlur.js
│ │ │ │ ├── backdropBlur.test.js
│ │ │ │ ├── getMarginDimensions.js
│ │ │ │ └── getMarginDimensions.test.js
│ │ └── mixins
│ │ │ ├── alignContent.js
│ │ │ ├── alignContent.test.js
│ │ │ ├── alignItems.js
│ │ │ ├── alignItems.test.js
│ │ │ ├── background.js
│ │ │ ├── background.test.js
│ │ │ ├── border.js
│ │ │ ├── border.test.js
│ │ │ ├── direction.js
│ │ │ ├── direction.test.js
│ │ │ ├── flex.js
│ │ │ ├── flex.test.js
│ │ │ ├── gap.js
│ │ │ ├── gap.test.js
│ │ │ ├── height.js
│ │ │ ├── height.test.js
│ │ │ ├── index.d.ts
│ │ │ ├── justifyContent.js
│ │ │ ├── justifyContent.test.js
│ │ │ ├── overflow.js
│ │ │ ├── overflow.test.js
│ │ │ ├── pseudos.js
│ │ │ ├── pseudos.test.js
│ │ │ ├── width.js
│ │ │ ├── width.test.js
│ │ │ ├── wrap.js
│ │ │ └── wrap.test.js
│ ├── toggle
│ │ ├── README.md
│ │ ├── __snapshots__
│ │ │ └── toggle.test.js.snap
│ │ ├── index.js
│ │ ├── styled.js
│ │ ├── toggle.d.ts
│ │ ├── toggle.js
│ │ ├── toggle.stories.js
│ │ ├── toggle.storiess.js
│ │ └── toggle.test.js
│ └── typography
│ │ ├── README.md
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.test.js
│ │ ├── list.js
│ │ ├── mixins
│ │ ├── index.d.ts
│ │ ├── textAlign.js
│ │ ├── textAlign.test.js
│ │ ├── textDecoration.js
│ │ ├── textDecoration.test.js
│ │ ├── truncate.js
│ │ ├── truncate.test.js
│ │ ├── whiteSpace.js
│ │ ├── whiteSpace.test.js
│ │ ├── wordBreak.js
│ │ └── wordBreak.test.js
│ │ ├── typography.js
│ │ └── typography.stories.js
├── global-styles.js
├── hooks
│ ├── useColor
│ │ ├── index.js
│ │ └── index.test.js
│ ├── useDebounce
│ │ └── index.js
│ ├── useDebouncedValue
│ │ └── index.js
│ ├── useDropElement
│ │ ├── index.js
│ │ └── index.test.js
│ ├── useForwardRef
│ │ ├── index.js
│ │ └── index.test.js
│ ├── useIntersection
│ │ └── index.js
│ ├── useKeyboardEsc
│ │ ├── index.js
│ │ └── index.test.js
│ ├── useMeasure
│ │ └── index.js
│ ├── useMountedRef
│ │ └── index.js
│ ├── useOutsideClick
│ │ ├── index.js
│ │ └── index.test.js
│ ├── usePrevious
│ │ └── index.js
│ ├── useToggle
│ │ ├── index.js
│ │ └── index.test.js
│ └── useUpdateEffect
│ │ └── index.js
├── index.js
├── media.js
├── mixins
│ ├── alignSelf.js
│ ├── alignSelf.test.js
│ ├── controlFocused.js
│ ├── controlReset.js
│ ├── cursor.js
│ ├── cursor.test.js
│ ├── index.js
│ ├── margin.js
│ ├── margin.test.js
│ ├── opacity.js
│ ├── opacity.test.js
│ ├── padding.js
│ ├── padding.test.js
│ ├── position.js
│ ├── position.test.js
│ ├── round.js
│ ├── round.test.js
│ ├── set-ref
│ │ └── index.js
│ ├── textTransform.js
│ ├── textTransform.test.js
│ ├── types.d.ts
│ ├── utils.js
│ ├── uuid
│ │ ├── index.js
│ │ └── index.test.js
│ ├── webkitVisibleScrollbar.js
│ ├── zIndex.js
│ └── zIndex.test.js
├── organisms
│ ├── documentation
│ │ ├── README.md
│ │ ├── dashboard
│ │ │ ├── index.js
│ │ │ ├── mouse.js
│ │ │ ├── section.js
│ │ │ └── touch.js
│ │ ├── general.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ └── search
│ │ │ ├── discourse
│ │ │ ├── api.js
│ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ ├── input.js
│ │ │ ├── provider.js
│ │ │ ├── results.js
│ │ │ └── utils.js
│ ├── navigation
│ │ ├── hooks
│ │ │ ├── useNavigationArrows.js
│ │ │ ├── useNavigationScroll.js
│ │ │ └── useOnTabsResize.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ ├── sortable
│ │ │ ├── arrow.js
│ │ │ ├── container.js
│ │ │ ├── index.js
│ │ │ └── item.js
│ │ ├── tab
│ │ │ ├── index.js
│ │ │ ├── tabSeparator.js
│ │ │ ├── use-styles-tab.js
│ │ │ └── use-styles-tab.test.js
│ │ └── tabs
│ │ │ └── index.js
│ ├── news
│ │ ├── README.md
│ │ ├── container.js
│ │ ├── header.js
│ │ ├── index.d.ts
│ │ ├── index.js
│ │ ├── index.stories.js
│ │ ├── item
│ │ │ ├── anchor.js
│ │ │ ├── image.js
│ │ │ └── index.js
│ │ └── useFetchNews.js
│ └── topbar
│ │ └── index.js
├── theme
│ ├── README.md
│ ├── dark
│ │ ├── colors.js
│ │ └── index.js
│ ├── default
│ │ ├── colors.js
│ │ ├── constants.js
│ │ └── index.js
│ ├── index.d.ts
│ ├── index.js
│ ├── rawColors.js
│ └── utils.js
└── utils
│ ├── assertions.js
│ ├── capitalizeFirstLetter.js
│ ├── capitalizeFirstLetter.test.js
│ ├── index.js
│ ├── mergeRefs.js
│ └── useContextSelector
│ └── index.js
├── utils
├── index.js
└── readme.js
├── webpack.config.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .vscode/
3 | .jest-test-results.json
4 | .jest-tmp
5 | .idea
6 | node_modules
7 | public
8 | lib
9 | coverage/
10 | dist
11 | coverage
12 | storybook-static/
13 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | trailingComma: "es5",
3 | semi: false,
4 | tabWidth: 2,
5 | printWidth: 100,
6 | useTabs: false,
7 | singleQuote: false,
8 | arrowParens: "avoid",
9 | }
10 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | const isES6 = process.env.BABEL_ENV === "es6"
2 | const isTest = process.env.NODE_ENV === "test"
3 |
4 | module.exports = {
5 | presets: [
6 | ["@babel/env", { loose: true, modules: isES6 ? false : "commonjs" }],
7 | "@babel/preset-react",
8 | ],
9 | plugins: [
10 | ["styled-components", { ssr: !isTest, displayName: !isTest }],
11 | "@babel/plugin-transform-spread",
12 | "@babel/plugin-proposal-object-rest-spread",
13 | [
14 | "module-resolver",
15 | {
16 | alias: {
17 | "@": "./src",
18 | },
19 | },
20 | ],
21 | ].filter(Boolean),
22 | env: {
23 | test: {
24 | presets: ["@babel/env"],
25 | plugins: ["@babel/transform-runtime"],
26 | },
27 | },
28 | }
29 |
--------------------------------------------------------------------------------
/jest/setup.js:
--------------------------------------------------------------------------------
1 | class ResizeObserver {
2 | observe() {}
3 | unobserve() {}
4 | disconnect() {}
5 | }
6 |
7 | window.ResizeObserver = ResizeObserver
8 |
--------------------------------------------------------------------------------
/jest/setupForEach.js:
--------------------------------------------------------------------------------
1 | import "jest-styled-components"
2 |
3 | afterEach(() => jest.restoreAllMocks())
4 | afterEach(() => jest.clearAllMocks())
5 | afterEach(() => jest.clearAllTimers())
6 |
7 | jest.setTimeout(10000)
8 | jest.retryTimes(2)
9 |
10 | Element.prototype.getOriginalBoundingClientRect = Element.prototype.getBoundingClientRect
11 | Element.prototype.getBoundingClientRect = jest.fn(() => {
12 | return {
13 | width: 120,
14 | height: 120,
15 | top: 0,
16 | left: 0,
17 | bottom: 0,
18 | right: 0,
19 | }
20 | })
21 |
--------------------------------------------------------------------------------
/jest/testUtilities/index.js:
--------------------------------------------------------------------------------
1 | import "@testing-library/jest-dom/jest-globals"
2 |
3 | export { default as renderWithProviders } from "./renderWithProviders"
4 | export { default as renderHookWithProviders } from "./renderHookWithProviders"
5 |
6 | import userEvent from "@testing-library/user-event"
7 | export const user = () => userEvent.setup()
8 | export { userEvent }
9 |
10 | export * from "@testing-library/react"
11 |
--------------------------------------------------------------------------------
/jest/testUtilities/renderHookWithProviders.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { renderHook } from "."
3 | import { ThemeProvider } from "styled-components"
4 | import { DefaultTheme } from "@/theme/default"
5 |
6 | export default (hook, { theme = DefaultTheme, ...rest } = {}) =>
7 | renderHook(hook, {
8 | wrapper: props => ,
9 | ...rest,
10 | })
11 |
--------------------------------------------------------------------------------
/jest/testUtilities/renderWithProviders.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { render } from "."
3 | import { ThemeProvider } from "styled-components"
4 | import { DefaultTheme } from "@/theme/default"
5 |
6 | export default (Component, { theme = DefaultTheme, ...rest } = {}) =>
7 | render(Component, {
8 | wrapper: props => ,
9 | ...rest,
10 | })
11 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "exclude": ["node_modules", "./fixtures/*"],
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./src/*"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/__mocks__/filemock.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | const Mock = () => <>test>
4 |
5 | export default Mock
6 |
--------------------------------------------------------------------------------
/src/components/animation/index.d.ts:
--------------------------------------------------------------------------------
1 | import { FC, ReactNode } from "react"
2 |
3 | export interface AnimationProps {
4 | open?: boolean
5 | duration?: number
6 | persist?: boolean
7 | children: ReactNode | (() => ReactNode)
8 | [rest: string]: any
9 | }
10 |
11 | declare const Animation: FC
12 |
13 | export { Animation }
14 |
15 | export default Animation
16 |
--------------------------------------------------------------------------------
/src/components/animation/makeAnimations.js:
--------------------------------------------------------------------------------
1 | import {keyframes, css} from 'styled-components';
2 |
3 | export default ({toggle, timing = '', speed = 200, transformOrigin}) => {
4 | const makeAnimations = keyframe => css`
5 | ${transformOrigin && `transform-origin: ${transformOrigin};`}
6 | animation: ${keyframe} ${speed}ms ${timing};
7 | `;
8 | return {
9 | entering: makeAnimations(keyframes`from { ${toggle} }`),
10 | exiting: makeAnimations(keyframes`to { ${toggle} }`)
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/src/components/button/constants.js:
--------------------------------------------------------------------------------
1 | export const DEFAULT = "default"
2 | export const HOLLOW = "hollow"
3 | export const BORDER_LESS = "borderless"
4 |
--------------------------------------------------------------------------------
/src/components/button/index.js:
--------------------------------------------------------------------------------
1 | export { Button } from "./button"
2 | export { default as IconButton } from "./iconButton"
3 | export { ButtonGroup } from "./buttonGroup"
4 |
--------------------------------------------------------------------------------
/src/components/checkbox/hooks.js:
--------------------------------------------------------------------------------
1 | import { useCallback } from "react"
2 |
3 | export const useCheckboxesList = (values, handlers) => {
4 | const checked = values.every(isChecked => isChecked)
5 | const isIndeterminate = !checked && values.includes(false) && values.includes(true)
6 |
7 | const switchAllCheckboxes = useCallback(() => {
8 | if (checked) {
9 | handlers.forEach(handler => handler(false))
10 | } else {
11 | handlers.forEach(handler => handler(true))
12 | }
13 | }, [checked, handlers])
14 |
15 | return [checked, isIndeterminate, switchAllCheckboxes]
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/checkbox/index.js:
--------------------------------------------------------------------------------
1 | export { Checkbox } from "./checkbox"
2 | export { useCheckboxesList } from "./hooks"
3 |
--------------------------------------------------------------------------------
/src/components/collapsible/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react"
2 | import { FlexProps } from "../templates/flex"
3 |
4 | export interface CollapsibleProps {
5 | open?: boolean
6 | duration?: number
7 | persist?: boolean
8 | children: ReactNode | (() => ReactNode)
9 | [rest: string]: any
10 | }
11 |
12 | declare const Collapsible: React.FC
13 |
14 | export { Collapsible }
15 |
16 | export default Collapsible
17 |
--------------------------------------------------------------------------------
/src/components/confirmation-dialog/confirmation-dialog.d.ts:
--------------------------------------------------------------------------------
1 | import { FC, SyntheticEvent } from "react"
2 |
3 | type OnClickType = (e: SyntheticEvent) => void
4 |
5 | export interface ConfirmationDialogProps {
6 | confirmLabel?: string
7 | confirmWidth?: string
8 | "data-ga"?: string
9 | "data-testid"?: string
10 | declineLabel?: string
11 | declineWidth?: string
12 | handleConfirm: OnClickType
13 | handleDecline?: OnClickType
14 | hideIcon?: boolean
15 | iconName?: string
16 | isConfirmDisabled?: boolean
17 | isConfirmPositive?: boolean
18 | message: JSX.Element | string
19 | title: string
20 | }
21 |
22 | declare const ConfirmationDialog: FC
23 |
24 | export { ConfirmationDialog }
25 |
26 | export default ConfirmationDialog
27 |
--------------------------------------------------------------------------------
/src/components/confirmation-dialog/index.js:
--------------------------------------------------------------------------------
1 | export { default as ConfirmationDialog } from "./confirmation-dialog"
2 |
--------------------------------------------------------------------------------
/src/components/drops/drop/index.d.ts:
--------------------------------------------------------------------------------
1 | import { FlexProps } from "../../templates/flex"
2 | import { AlignProps, StretchProps } from "../mixins"
3 |
4 | export interface DropProps extends FlexProps, AlignProps, StretchProps {
5 | backdrop?: boolean
6 | backdropProps?: any
7 | canHideTarget?: boolean
8 | children: any
9 | hideShadow?: boolean
10 | onClickOutside?: Function
11 | onEsc?: Function
12 | target: object
13 | [key: string]: any
14 | }
15 |
16 | declare const Drop: React.FC
17 |
18 | export { Drop }
19 |
20 | export default Drop
21 |
--------------------------------------------------------------------------------
/src/components/drops/mixins/dropAlignMap.js:
--------------------------------------------------------------------------------
1 | export default {
2 | top: { bottom: "top" },
3 | left: { right: "left" },
4 | right: { left: "right" },
5 | bottom: { top: "bottom" },
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/drops/mixins/getAncestors.js:
--------------------------------------------------------------------------------
1 | export default node => {
2 | const ancestors = []
3 |
4 | node = node.parentNode
5 | while (node) {
6 | ancestors.push(node)
7 | node = node.parentNode
8 | }
9 |
10 | return ancestors
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/drops/mixins/isAncestor.js:
--------------------------------------------------------------------------------
1 | import getAncestors from "./getAncestors"
2 |
3 | export default (parent, target) => getAncestors(target).some(node => node === parent)
4 |
--------------------------------------------------------------------------------
/src/components/drops/mixins/useDescribedId.js:
--------------------------------------------------------------------------------
1 | import { useMemo } from "react"
2 | import uuid from "@/mixins/uuid"
3 |
4 | export default describedby => useMemo(() => describedby || uuid(), [])
5 |
--------------------------------------------------------------------------------
/src/components/drops/popover/README.md:
--------------------------------------------------------------------------------
1 | ## Popover component
2 |
3 | A popover flavored drop that is activating hovering a target element.
4 | The drop remains open while the cursor is hovering either the target or the drop content.
5 |
6 | ### Props:
7 |
8 | ```typescript
9 | interface PopoverProps {
10 | plain: boolean
11 | open: boolean
12 | align: "top" | "right" | "bottom" | "left"
13 | dropProps: DropProps
14 | content: any
15 | children: any
16 | [key: string]: any
17 | }
18 | ```
19 |
20 | ### Typical usage:
21 |
22 | ```JSX
23 | export const SimplePopover = props => {
24 | const ref = useRef()
25 |
26 | return (
27 |
28 | Target
29 |
30 | )
31 | }
32 | ```
33 |
--------------------------------------------------------------------------------
/src/components/drops/popover/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react"
2 | import { DropProps } from "../drop"
3 |
4 | export interface TooltipProps {
5 | plain?: boolean
6 | open?: boolean
7 | align?: "top" | "right" | "bottom" | "left"
8 | dropProps?: DropProps
9 | content: ReactNode | (() => ReactNode)
10 | children: any
11 | [key: string]: any
12 | }
13 |
14 | declare const Tooltip: React.FC
15 |
16 | export { Tooltip }
17 |
18 | export default Tooltip
19 |
--------------------------------------------------------------------------------
/src/components/drops/tooltip/README.md:
--------------------------------------------------------------------------------
1 | ## Tooltip component
2 |
3 | A tooltip flavored drop that is activating hovering a target element.
4 |
5 | ### Props:
6 |
7 | ```typescript
8 | interface TooltipProps {
9 | plain: boolean
10 | open: boolean
11 | align: "top" | "right" | "bottom" | "left"
12 | dropProps: DropProps
13 | content: any
14 | children: any
15 | [key: string]: any
16 | }
17 | ```
18 |
19 | ### Typical usage:
20 |
21 | ```JSX
22 | export const SimpleTooltip = props => {
23 | const ref = useRef()
24 |
25 | return (
26 |
27 | Target
28 |
29 | )
30 | }
31 | ```
32 |
--------------------------------------------------------------------------------
/src/components/drops/tooltip/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode, FC } from "react"
2 | import { DropProps } from "../drop"
3 |
4 | export interface PopoverProps {
5 | plain?: boolean
6 | open?: boolean
7 | align?: "top" | "right" | "bottom" | "left"
8 | dropProps?: DropProps
9 | content: ReactNode | (() => ReactNode)
10 | children: any
11 | allowHoverOnTooltip?: boolean
12 | [key: string]: any
13 | }
14 |
15 | declare const Popover: FC
16 |
17 | export { Popover }
18 |
19 | export default Popover
20 |
--------------------------------------------------------------------------------
/src/components/icon/assets/add_node.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/add_user.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/aggregation_avg.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/aggregation_max.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/aggregation_med.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/aggregation_min.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/aggregation_sum.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/aggregation_sum_abs.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/alarm.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/alarm_c.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/alarm_w.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/alarms_new.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/area_chart.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/around_clock.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/arrow-s_down.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/arrow-s_left.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/arrow_down.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/arrow_left.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/arrow_w_line_left.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/arrow_w_line_right.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/arrows_vertical.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/bar_chart.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/bookmark.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/bullet_one.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/bullet_three.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/bullet_two.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/calendar_full.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/calendar_full_press.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chart_added.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chart_bars.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chart_pie.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/charts.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/check.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/checkmark.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/checkmark_partial_s.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_double.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_down.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_down_thin.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_expand.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_left.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_left_small.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_left_start.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_right.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_right_end.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_right_s.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_right_small.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/chevron_up_thin.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/close_circle.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/cluster.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/cluster_spaces.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/collapse.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/collect.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/community.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/connectivity_status_offline.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/connectivity_status_stale.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/container.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/controller_kind.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/copy.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/cpu.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/cross_s.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/dashboard.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/dashboards.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/disk.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/documentation.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/dot.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/dots_2x3.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/download.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/drag_horizontal.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/drag_vertical.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/error.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/components/icon/assets/exclamation.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/expand.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/favorites.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/filter.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/filterList.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/firewall_solid.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/force_play.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/force_play_outline.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/go_to_node.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/grid.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/group_by.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/h1.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/h2.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/hamburger.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/heatmap_chart.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/help.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/hide.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/holder.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/importExport.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/information_press.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/integrations/pagerduty.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/integrations/pagerduty_colored.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/ipNetworking.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/ipNetworkingPress.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/last_week.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/line_chart2.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/loading.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/logo_s.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/long_arrow_up.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/magnify.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/minimize_s.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/misc_select.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/monitoring.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/more.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/nav_arrow_goto.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/nav_dots.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/nav_left.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/nav_right.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/netdata-press.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/netdataAssistant.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/node.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/node_child.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/node_hollow.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/node_parent.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/nodes_hollow.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/none_selected.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/os/alpine_linux.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/os/coreOS.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/os/linux_manjaro.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/os/macOSX.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/os/oracle.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/os/oracle_colored.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/os/windows.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/padlock.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/pause_outline.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/pause_solid.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/pencil_outline.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/pencil_solid.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/pin_element.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/play_outline.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/play_solid.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/plus.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/plus_mini_s.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/pod.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/print.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/question.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/questionFilled.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/ram.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/rearrange.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/reload.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/reload2.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/resize_handler.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/room.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/room_home.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/room_new.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/save.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/save2.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/search.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/search_press.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/search_s.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/select.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/containerTech.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/lighthttpd.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/lighthttpd2.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/lxc.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/openStack.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/pandas.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/percona.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/pfSense.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/rabbitMQ.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/selected_area.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/sendgrid.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/solr.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/summary_statistic.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/systemd.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/varnish.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/icon/assets/services/webLog_nginx.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/sort_ascending.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/sort_descending.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/sorting_asc.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/sorting_desc.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/sorting_vertical.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/space_new.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/stacked_chart.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/switch_off.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/system_overview_press.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/text_add.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/thumb_down.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/thumb_up.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/top.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/triangle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/triangle_down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/icon/assets/unreachable.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/update.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/upload.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/user.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/user_press.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/users.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/value.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/components/icon/assets/view_list.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/virtualization.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/weights_drill_down.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/assets/x.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/components/icon/components/index.js:
--------------------------------------------------------------------------------
1 | export { LoaderIcon } from "./loader"
2 |
--------------------------------------------------------------------------------
/src/components/icon/icon.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { iconsList } from "./iconsList"
3 | import { StyledIcon } from "./styled"
4 |
5 | const getSize = filename => {
6 | if (filename.endsWith("_s")) {
7 | return "small"
8 | }
9 | if (filename.endsWith("_l")) {
10 | return "large"
11 | }
12 | return "medium"
13 | }
14 |
15 | export const Icon = ({ name, size, ref, ...rest }) => {
16 | const iconSymbol = iconsList[name]
17 |
18 | if (!iconSymbol) {
19 | return null
20 | }
21 |
22 | const iconSize = size || getSize(name)
23 |
24 | return (
25 |
26 |
27 |
28 | )
29 | }
30 |
--------------------------------------------------------------------------------
/src/components/icon/icon.stories.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { iconsList } from "./iconsList"
3 | import { Icon } from "."
4 |
5 | export const Basic = args =>
6 |
7 | export default {
8 | component: Icon,
9 | args: {
10 | name: Object.keys(iconsList)[0],
11 | size: "small",
12 | disabled: false,
13 | },
14 | argTypes: {
15 | name: {
16 | options: Object.keys(iconsList),
17 | control: { type: "select" },
18 | },
19 | size: {
20 | options: ["small", "medium", "large"],
21 | control: { type: "radio" },
22 | },
23 | disabled: { control: "boolean" },
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/icon/index.d.ts:
--------------------------------------------------------------------------------
1 | import { FC } from "react"
2 | import { AlignSelfProps, ColorType, MarginProps, RefType } from "@/mixins/types"
3 |
4 | export interface IconProps extends MarginProps, AlignSelfProps {
5 | className?: string
6 | color?: ColorType
7 | disabled?: boolean
8 | "data-testid"?: string
9 | height?: string
10 | hoverColor?: ColorType
11 | name: string
12 | onClick?: (arg?: any) => void
13 | ref?: RefType
14 | size?: "small" | "medium" | "large"
15 | title?: string
16 | width?: string
17 | }
18 |
19 | declare const Icon: FC
20 |
21 | export { Icon }
22 |
23 | export default Icon
24 |
--------------------------------------------------------------------------------
/src/components/icon/index.js:
--------------------------------------------------------------------------------
1 | import * as IconComponents from "./components"
2 |
3 | export { IconComponents }
4 | export { iconsList } from "./iconsList"
5 | export * from "./icon"
6 |
--------------------------------------------------------------------------------
/src/components/input/index.js:
--------------------------------------------------------------------------------
1 | export * from "./input"
2 | export { default as MultiRangeInput } from "./multiRange"
3 | export { useTouchedState } from "./use-touched-state"
4 | export { useFocusedState } from "./use-focused-state"
5 | export { useInputValue } from "./use-input-value"
6 |
--------------------------------------------------------------------------------
/src/components/input/input.test.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { renderWithProviders } from "testUtilities"
3 | import { TextInputMock } from "./input.mock"
4 |
5 | describe("TextInput test", () => {
6 | it(" * should render with required props", () => {
7 | const { container } = renderWithProviders()
8 | const result = container.querySelectorAll("input")
9 | expect(result).not.toBeNull()
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/src/components/input/multiRange/index.d.ts:
--------------------------------------------------------------------------------
1 | import { FC, SyntheticEvent } from "react"
2 |
3 | export interface MultiRangeInputProps {
4 | "data-testid"?: string
5 | initMax?: number
6 | initMin?: number
7 | max?: number
8 | min?: number
9 | onChange: ({ max, min }) => void
10 | onClick?: (e: SyntheticEvent) => void
11 | onInput?: ({ max, min }) => void
12 | step?: number
13 | TextComponent?: FC
14 | }
15 |
16 | declare const MultiRangeInput: FC
17 |
18 | export { MultiRangeInput }
19 |
20 | export default MultiRangeInput
21 |
--------------------------------------------------------------------------------
/src/components/input/range/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ChangeEvent, FC, SyntheticEvent } from "react"
2 |
3 | export interface RangeInputProps {
4 | "data-testid"?: string
5 | max?: number
6 | min?: number
7 | onChange: (e: ChangeEvent) => void
8 | onClick?: (e: SyntheticEvent) => void
9 | onInput?: (e: SyntheticEvent) => void
10 | step?: number
11 | value: number
12 | }
13 |
14 | declare const RangeInput: FC
15 |
16 | export { RangeInput }
17 |
18 | export default RangeInput
19 |
--------------------------------------------------------------------------------
/src/components/input/range/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { InputRange as StyledInputRange } from "./styled"
3 |
4 | const InputRange = ({ max = 100, min = 0, step = 1, value = 0, ref, ...rest }) => (
5 |
15 | )
16 |
17 | export default InputRange
18 |
--------------------------------------------------------------------------------
/src/components/input/range/range.test.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import RangeInput from "./index"
3 | import { renderWithProviders, screen } from "testUtilities"
4 |
5 | const setup = props => renderWithProviders()
6 |
7 | describe("InputRange component", () => {
8 | test("should render component", () => {
9 | setup()
10 | expect(screen.getByTestId("rangeInput")).toBeInTheDocument()
11 | })
12 | })
13 |
--------------------------------------------------------------------------------
/src/components/input/use-focused-state.js:
--------------------------------------------------------------------------------
1 | import { useState, useCallback } from "react"
2 |
3 | export const useFocusedState = ({ defaultState = false, onBlur, onFocus }) => {
4 | const [focused, setFocused] = useState(defaultState)
5 |
6 | const handleFocus = useCallback(
7 | e => {
8 | if (!focused) {
9 | setFocused(true)
10 | }
11 | if (onFocus) {
12 | onFocus(e)
13 | }
14 | },
15 | [onFocus, focused]
16 | )
17 | const handleBlur = useCallback(
18 | e => {
19 | setFocused(false)
20 | if (onBlur) {
21 | onBlur(e)
22 | }
23 | },
24 | [onBlur]
25 | )
26 |
27 | return [focused, handleFocus, handleBlur]
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/input/use-input-value.d.ts:
--------------------------------------------------------------------------------
1 | import { ChangeEvent } from "react"
2 |
3 | export interface UseInputValueProps {
4 | maxChars?: number
5 | onChange?: (e: ChangeEvent) => void
6 | value?: string
7 | }
8 |
9 | declare const useInputValue: (props: UseInputValueProps) =>
10 | [
11 | string,
12 | (e: ChangeEvent) => void,
13 | string,
14 | boolean,
15 | {
16 | setIsDirty: (state: boolean) => void,
17 | setValue: (state: string) => void,
18 | resetValue: () => void
19 | }
20 | ]
21 |
22 | export { useInputValue }
23 |
24 | export default useInputValue
25 |
--------------------------------------------------------------------------------
/src/components/input/use-touched-state.d.ts:
--------------------------------------------------------------------------------
1 | import { FocusEvent } from "react"
2 |
3 | export interface UseTouchedStateProps {
4 | onBlur?: (e: FocusEvent) => void
5 | defaultState?: boolean
6 | }
7 |
8 | declare const useTouchedState: (props: UseTouchedStateProps) =>
9 | [
10 | boolean,
11 | (e: FocusEvent) => void,
12 | (state: boolean) => void
13 | ]
14 |
15 | export { useTouchedState }
16 |
17 | export default useTouchedState
18 |
--------------------------------------------------------------------------------
/src/components/input/use-touched-state.js:
--------------------------------------------------------------------------------
1 | import { useState, useCallback } from "react"
2 |
3 | export const useTouchedState = ({ onBlur, defaultState = false }) => {
4 | const [touchedState, setTouchedState] = useState(defaultState)
5 | const handleBlur = useCallback(
6 | e => {
7 | if (!touchedState) {
8 | setTouchedState(true)
9 | }
10 | if (onBlur) {
11 | onBlur(e)
12 | }
13 | },
14 | [onBlur, touchedState]
15 | )
16 |
17 | return [touchedState, handleBlur, setTouchedState]
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/intersection/README.md:
--------------------------------------------------------------------------------
1 | ## Popover component
2 |
3 | A component that displays the fallback until it is visible to the viewport.
4 | It uses the IntersectionObserver.
5 |
6 | ### Props:
7 |
8 | ```typescript
9 | interface IntersectionProps {
10 | root: object
11 | rootMargin: string
12 | threshold: number
13 | fallback: ReactNode | (() => ReactNode)
14 | children: ReactNode | (() => ReactNode)
15 | [key: string]: any
16 | }
17 | ```
18 |
19 | ### Typical usage:
20 |
21 | ```JSX
22 | export const Component = () => {
23 | return (
24 |
25 | This is visible inside the viewport
26 |
27 | )
28 | }
29 | ```
30 |
--------------------------------------------------------------------------------
/src/components/intersection/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react"
2 | import { FlexProps } from "../templates/flex"
3 |
4 | export interface IntersectionProps extends FlexProps {
5 | root: object
6 | rootMargin: string
7 | threshold: number
8 | fallback: ReactNode | (() => ReactNode)
9 | children: ReactNode | (() => ReactNode)
10 | [key: string]: any
11 | }
12 |
13 | declare const Intersection: React.FC
14 |
15 | export { Intersection }
16 |
17 | export default Intersection
18 |
--------------------------------------------------------------------------------
/src/components/intersection/index.stories.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Flex from "@/components/templates/flex"
3 | import Intersection from "."
4 |
5 | export const Basic = () => (
6 |
7 |
8 | Visible inside the viewport. Scroll down and see the inspect element
9 |
10 |
11 | )
12 |
13 | export default {
14 | component: Intersection,
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/pill/alertMastercard.d.ts:
--------------------------------------------------------------------------------
1 | import { FC } from "react"
2 | import { MasterCardProps } from "./mastercard"
3 |
4 | declare const AlertMasterCard: FC
5 |
6 | export { AlertMasterCard }
7 |
8 | export default AlertMasterCard
9 |
--------------------------------------------------------------------------------
/src/components/pill/icon.d.ts:
--------------------------------------------------------------------------------
1 | import { FC } from "react"
2 | import { PillFlavour } from "./index"
3 | import { IconProps } from "../icon/index"
4 |
5 | export interface PillIconProps extends IconProps {
6 | icon?: string
7 | hollow?: boolean
8 | flavour?: PillFlavour
9 | }
10 |
11 | declare const PillIcon: FC
12 |
13 | export { PillIcon }
14 |
15 | export default PillIcon
16 |
--------------------------------------------------------------------------------
/src/components/pill/icon.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Icon } from "@/components/icon"
3 | import { getPillColor } from "./mixins/colors"
4 |
5 | const sizes = {
6 | default: "14px",
7 | large: "16px",
8 | }
9 |
10 | const PillIcon = ({ icon, color, hollow, flavour, size, ...rest }) => {
11 | if (!icon) return null
12 | if (typeof icon !== "string") return icon
13 |
14 | return (
15 |
23 | )
24 | }
25 |
26 | export default PillIcon
27 |
--------------------------------------------------------------------------------
/src/components/pill/mastercardPill.d.ts:
--------------------------------------------------------------------------------
1 | import { FC } from "react"
2 | import { PillProps } from "./index"
3 |
4 | export interface MasterCardPillProps extends PillProps {
5 | text?: string
6 | }
7 |
8 | declare const MasterCardPill: FC
9 |
10 | export { MasterCardPill }
11 |
12 | export default MasterCardPill
13 |
--------------------------------------------------------------------------------
/src/components/pill/mastercardPill.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Pill from "./index"
3 |
4 | const MasterCardPill = ({ background, icon, text, ref, ...rest }) => (
5 |
13 | {!icon && (text || "-")}
14 |
15 | )
16 |
17 | export default MasterCardPill
18 |
--------------------------------------------------------------------------------
/src/components/pill/mixins/background.js:
--------------------------------------------------------------------------------
1 | import { getMasterCardColor, getPillColor } from "./colors"
2 |
3 | export const getMasterCardBackground = (background, flavour) =>
4 | background || getMasterCardColor(flavour)
5 |
6 | const getPillBackground = ({ background, flavour = "neutral", hollow, semi }) => {
7 | if (background) return background
8 | if (hollow) return semi ? getPillColor("hollow", flavour) : "transparent"
9 |
10 | return getPillColor("background", flavour)
11 | }
12 |
13 | export default getPillBackground
14 |
--------------------------------------------------------------------------------
/src/components/pill/mixins/height.js:
--------------------------------------------------------------------------------
1 | const pillHeights = {
2 | default: "18px",
3 | large: "22px",
4 | }
5 |
6 | const getPillHeight = (height, size, tiny) => {
7 | if (height) return height
8 | if (tiny) return "8px"
9 | return pillHeights[size] || pillHeights.default
10 | }
11 |
12 | export default getPillHeight
13 |
--------------------------------------------------------------------------------
/src/components/pill/mixins/padding.js:
--------------------------------------------------------------------------------
1 | const paddings = {
2 | default: [0.5, 2],
3 | large: [1, 2.5],
4 | }
5 |
6 | const getPillPadding = (padding, size, tiny) => {
7 | if (padding) return padding
8 | if (tiny) return [0.25, 0.5]
9 | return paddings[size] || paddings.default
10 | }
11 |
12 | export default getPillPadding
13 |
--------------------------------------------------------------------------------
/src/components/pill/mixins/width.js:
--------------------------------------------------------------------------------
1 | const getPillWidth = (width, tiny) => {
2 | if (width) return width
3 | return tiny && "auto"
4 | }
5 |
6 | export default getPillWidth
7 |
--------------------------------------------------------------------------------
/src/components/progressBar/index.d.ts:
--------------------------------------------------------------------------------
1 | import { FC } from "react"
2 |
3 | export interface Value {
4 | color?: string
5 | width?: string
6 | [key: string]: any
7 | }
8 |
9 | export interface ProgressBarProps {
10 | background?: string
11 | className?: string
12 | color?: string
13 | "data-testid"?: string
14 | containerWidth?: string
15 | height?: number
16 | value?: Value[]
17 | width?: string
18 | [s: string]: any
19 | }
20 |
21 | declare const ProgressBar: FC
22 |
23 | export { ProgressBar }
24 |
25 | export default ProgressBar
26 |
--------------------------------------------------------------------------------
/src/components/progressBar/index.stories.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Flex from "@/components/templates/flex"
3 | import ProgressBar from "."
4 |
5 | export const Basic = () => (
6 |
7 |
8 |
9 | )
10 |
11 | export const WithValue = () => (
12 |
13 |
20 |
21 | )
22 |
23 | export default {
24 | component: ProgressBar,
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/radio-button/index.d.ts:
--------------------------------------------------------------------------------
1 | import { MarginProps, AlignSelfProps } from "../../mixins/types"
2 |
3 | export interface RadioButtonProps extends MarginProps, AlignSelfProps {
4 | label?: React.ReactNode
5 | checked?: boolean
6 | disabled?: boolean
7 | name?: string
8 | iconProps?: {
9 | [key: string]: any
10 | }
11 | children?: React.ReactNode
12 | }
13 |
14 | declare const RadioButton: React.FC
15 |
16 | export { RadioButton }
17 |
18 | export default RadioButton
19 |
--------------------------------------------------------------------------------
/src/components/radio-button/mixins/disabled.js:
--------------------------------------------------------------------------------
1 | export default ({ disabled }) =>
2 | `
3 | pointer-events: ${disabled ? "none" : "auto"};
4 | cursor: ${disabled ? "default" : "pointer"};
5 | `
6 |
--------------------------------------------------------------------------------
/src/components/radio-button/mixins/disabled.test.js:
--------------------------------------------------------------------------------
1 | import disabled from "./disabled"
2 |
3 | it("renders", () => {
4 | expect(disabled({})).toBe(`
5 | pointer-events: auto;
6 | cursor: pointer;
7 | `)
8 | })
9 |
10 | it("renders disabled", () => {
11 | expect(disabled({ disabled: true })).toBe(`
12 | pointer-events: none;
13 | cursor: default;
14 | `)
15 | })
16 |
--------------------------------------------------------------------------------
/src/components/select/index.d.ts:
--------------------------------------------------------------------------------
1 | import { FC } from "react"
2 | import { Props } from "react-select"
3 |
4 | export interface SelectProps extends Props {
5 | "data-ga"?: string;
6 | "data-testid"?: string;
7 | }
8 |
9 | declare const Select: FC
10 |
11 | export { Select }
12 |
13 | export default Select
14 |
--------------------------------------------------------------------------------
/src/components/sidebar/index.js:
--------------------------------------------------------------------------------
1 | export { Sidebar } from "./sidebar"
2 | export { PortalSidebar } from "./portaled-sidebar"
3 |
--------------------------------------------------------------------------------
/src/components/sidebar/portaled-sidebar.d.ts:
--------------------------------------------------------------------------------
1 | import { FC, ReactNode } from "react"
2 |
3 | export interface PortalSidebarProps {
4 | className?: string
5 | closeOnEsc?: boolean
6 | closeOnOverlayClick?: boolean
7 | "data-testid"?: string
8 | onClose?: () => {}
9 | right?: boolean
10 | Wrapper: ReactNode
11 | [s: string]: any
12 | }
13 |
14 | declare const PortalSidebar: FC
15 |
16 | export { PortalSidebar }
17 |
18 | export default PortalSidebar
19 |
--------------------------------------------------------------------------------
/src/components/sidebar/sidebar.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { SidebarBox, ComponentBox, InfoBox } from "./styled"
3 |
4 | export const Sidebar = ({ info, children, className, right = false }) => (
5 |
6 |
7 | {children}
8 |
9 | {info}
10 |
11 | )
12 |
--------------------------------------------------------------------------------
/src/components/table/body/header/filter/dropdown.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Select from "@/components/select"
3 |
4 | const DropdownFilter = ({
5 | "data-ga": dataGA,
6 | "data-testid": dataTestId,
7 | onChange,
8 | value,
9 | options,
10 | isMulti,
11 | styles,
12 | }) => (
13 |
22 | )
23 |
24 | export default DropdownFilter
25 |
--------------------------------------------------------------------------------
/src/components/table/body/header/filter/search.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Box from "@/components/templates/box"
3 | import { Icon } from "@/components/icon"
4 | import SearchInput from "@/components/search"
5 |
6 | const SearchFilter = ({ column, testPrefix }) => {
7 | const { id = "" } = column
8 |
9 | return (
10 | }
17 | onChange={column.setFilterValue}
18 | />
19 | )
20 | }
21 |
22 | export default SearchFilter
23 |
--------------------------------------------------------------------------------
/src/components/table/body/header/info.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { Icon } from "@/components/icon"
3 | import Flex from "@/components/templates/flex"
4 | import Tooltip from "@/components/drops/tooltip"
5 |
6 | const Info = ({ meta }) => {
7 | const tooltipText = meta && meta?.tooltip ? meta?.tooltip : ""
8 |
9 | if (!tooltipText) return null
10 |
11 | return (
12 |
13 |
14 |
15 |
16 |
17 | )
18 | }
19 |
20 | export default Info
21 |
--------------------------------------------------------------------------------
/src/components/table/index.js:
--------------------------------------------------------------------------------
1 | export { default as Table } from "./table"
2 | export { default as downloadCsvAction } from "./helpers/downloadCsv"
3 |
--------------------------------------------------------------------------------
/src/components/table/useExpanding.js:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useRef, useState } from "react"
2 |
3 | const noop = () => {}
4 | const emptyObj = {}
5 |
6 | export default (defaultExpanded = emptyObj, onChange = noop) => {
7 | const initialSetRef = useRef(false)
8 | const [expanded, setExpanded] = useState(() => defaultExpanded)
9 |
10 | useEffect(() => {
11 | if (!defaultExpanded || expanded === defaultExpanded) return
12 |
13 | initialSetRef.current = true
14 | setExpanded(defaultExpanded)
15 | }, [defaultExpanded])
16 |
17 | const onExpand = useCallback(value => {
18 | onChange(value)
19 | setExpanded(value)
20 | }, [])
21 |
22 | return [expanded, onExpand]
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/table/useGrouping.js:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useRef, useState } from "react"
2 |
3 | const noop = () => {}
4 |
5 | export default (defaultGrouping = "", onChange = noop) => {
6 | const [grouping, setGrouping] = useState(defaultGrouping)
7 | const initialSetRef = useRef(false)
8 |
9 | useEffect(() => {
10 | if (grouping === defaultGrouping) return
11 |
12 | initialSetRef.current = true
13 | setGrouping(defaultGrouping)
14 | }, [defaultGrouping])
15 |
16 | const onGroupingChange = useCallback(value => {
17 | onChange(value)
18 | setGrouping(value)
19 | }, [])
20 |
21 | return [grouping, onGroupingChange]
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/table/usePaginating.js:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useState, useRef } from "react"
2 |
3 | const noop = () => {}
4 | const defaultPaginationOptions = { pageIndex: 0, pageSize: 0 }
5 |
6 | export default (paginationOptions = defaultPaginationOptions, onChange = noop) => {
7 | const [pagination, setPagination] = useState(() => paginationOptions)
8 | const initialSetRef = useRef(false)
9 |
10 | useEffect(() => {
11 | if (pagination === paginationOptions) return
12 |
13 | initialSetRef.current = true
14 | setPagination(paginationOptions)
15 | }, [paginationOptions])
16 |
17 | const onPaginationChange = useCallback(value => {
18 | onChange(value)
19 | setPagination(value)
20 | }, [])
21 |
22 | return [pagination, onPaginationChange]
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/table/usePinning.js:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useState, useRef } from "react"
2 |
3 | const noop = () => {}
4 | const emptyObj = {}
5 |
6 | export default (defaultPinning = emptyObj, onChange = noop) => {
7 | const [pinning, setPinning] = useState(() => defaultPinning)
8 | const initialSetRef = useRef(false)
9 |
10 | useEffect(() => {
11 | if (!defaultPinning || pinning === defaultPinning) return
12 |
13 | initialSetRef.current = true
14 | setPinning(defaultPinning)
15 | }, [defaultPinning])
16 |
17 | const onPin = useCallback(value => {
18 | onChange(value)
19 | setPinning(value)
20 | }, [])
21 |
22 | return [pinning, onPin]
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/table/useSearching.js:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useState, useRef } from "react"
2 |
3 | const noop = () => {}
4 |
5 | export default (defaultGlobalFilter = "", onChange = noop) => {
6 | const [globalFilter, setGlobalFilter] = useState(defaultGlobalFilter)
7 | const initialSetRef = useRef(false)
8 |
9 | useEffect(() => {
10 | if (globalFilter === defaultGlobalFilter) return
11 |
12 | initialSetRef.current = true
13 | setGlobalFilter(defaultGlobalFilter)
14 | }, [defaultGlobalFilter])
15 |
16 | const onGlobalFilterChange = useCallback(value => {
17 | onChange(value)
18 | setGlobalFilter(value)
19 | }, [])
20 |
21 | return [globalFilter, onGlobalFilterChange]
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/table/useSorting.js:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useState, useRef } from "react"
2 |
3 | const noop = () => {}
4 | const emptyArr = []
5 |
6 | export default (defaultSorting = emptyArr, onChange = noop) => {
7 | const [sorting, setSorting] = useState(() => defaultSorting)
8 | const initialSetRef = useRef(false)
9 |
10 | useEffect(() => {
11 | if (sorting === defaultSorting) return
12 |
13 | initialSetRef.current = true
14 | setSorting(defaultSorting)
15 | }, [defaultSorting])
16 |
17 | const onSortingChange = useCallback(
18 | getValue => {
19 | onChange(getValue(sorting))
20 | setSorting(getValue(sorting))
21 | },
22 | [sorting]
23 | )
24 |
25 | return [sorting, onSortingChange]
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/tabs/index.js:
--------------------------------------------------------------------------------
1 | export { Tabs } from "./tabs"
2 | export { Tab } from "./tab"
3 |
--------------------------------------------------------------------------------
/src/components/tabs/tab.d.ts:
--------------------------------------------------------------------------------
1 | import { ChangeEvent, FC } from "react"
2 |
3 | export interface TabProps {
4 | active?: boolean
5 | disabled?: boolean
6 | "data-testid"?: string
7 | index?: number
8 | label: JSX.Element | string
9 | maxWidth?: number | string
10 | minWidth?: number | string
11 | onChange?: (e: ChangeEvent) => void
12 | small?: boolean
13 | [s: string]: any
14 | }
15 |
16 | declare const Tab: FC
17 |
18 | export { Tab }
19 |
20 | export default Tab
21 |
--------------------------------------------------------------------------------
/src/components/tabs/tab.js:
--------------------------------------------------------------------------------
1 | import React, { useCallback } from "react"
2 | import { StyledTab, StyledTabMenu } from "./styled"
3 |
4 | export const Tab = ({ index, isMenuItem, onChange, ...rest }) => {
5 | const onClick = useCallback(e => onChange && onChange(index || 0, e), [index, onChange])
6 |
7 | const TabComponent = isMenuItem ? StyledTabMenu : StyledTab
8 | return (
9 |
15 | {rest.label}
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/src/components/tabs/tabs.d.ts:
--------------------------------------------------------------------------------
1 | import { ChangeEvent, FC, ReactNode } from "react"
2 |
3 | export interface TabsProps {
4 | className?: string
5 | "data-testid"?: string
6 | noDefaultBorder?: boolean
7 | onChange: (e: ChangeEvent) => void
8 | selected: boolean
9 | TabContent?: ReactNode
10 | TabsHeader?: ReactNode
11 | [s: string]: any
12 | }
13 |
14 | declare const Tabs: FC
15 |
16 | export { Tabs }
17 |
18 | export default Tabs
19 |
--------------------------------------------------------------------------------
/src/components/templates/box/README.md:
--------------------------------------------------------------------------------
1 | ## Box
2 |
3 | A Box container with all the frequently used properties.
4 |
5 | ### Props:
6 |
7 | ```typescript
8 | export type BoxProps = CombinedStyledProps & {
9 | as?: React.ElementType
10 | sx?: CombinedStyledProps
11 | }
12 | ```
13 |
14 | ### Typical usage:
15 |
16 | ```JSX
17 | export const Container = () => {
18 | return (
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | )
32 | }
33 | ```
34 |
--------------------------------------------------------------------------------
/src/components/templates/box/index.js:
--------------------------------------------------------------------------------
1 | import makeBox from "./box"
2 |
3 | const Box = makeBox("div")
4 |
5 | export default Box
6 |
--------------------------------------------------------------------------------
/src/components/templates/flex/index.js:
--------------------------------------------------------------------------------
1 | import makeFlex from "./flex"
2 |
3 | const Flex = makeFlex("div")
4 |
5 | export default Flex
6 |
--------------------------------------------------------------------------------
/src/components/templates/layer/README.md:
--------------------------------------------------------------------------------
1 | ## Layer
2 |
3 | An overlay container that aligns according to the page viewport. Useful for modals, sidebars, notifications, etc.
4 |
5 | ### Props:
6 |
7 | ```typescript
8 | export interface LayerProps extends MarginProps, FullProps, PositionProps {
9 | backdrop?: boolean
10 | onClickOutside?: Function
11 | onEsc?: Function
12 | borderShadow?: boolean
13 | }
14 | ```
15 |
16 | ### Typical usage:
17 |
18 | ```JSX
19 | export const Container = () => {
20 | return (
21 |
22 |
23 |
24 | Layer content
25 |
26 |
27 |
28 | )
29 | }
30 | ```
31 |
--------------------------------------------------------------------------------
/src/components/templates/layer/index.d.ts:
--------------------------------------------------------------------------------
1 | import { MarginProps } from "../../../mixins/types"
2 |
3 | export interface PositionProps {
4 | position?:
5 | | "top-left"
6 | | "top"
7 | | "top-right"
8 | | "left"
9 | | "center"
10 | | "right"
11 | | "bottom-left"
12 | | "bottom"
13 | | "bottom-right"
14 | }
15 |
16 | export interface FullProps {
17 | full?: boolean | "vertical" | "horizontal"
18 | }
19 |
20 | export interface LayerProps extends MarginProps, FullProps, PositionProps {
21 | backdrop?: boolean
22 | onClickOutside?: Function
23 | onEsc?: Function
24 | borderShadow?: boolean
25 | }
26 |
27 | declare const Layer: React.FC
28 |
29 | export { Layer }
30 |
31 | export default Layer
32 |
--------------------------------------------------------------------------------
/src/components/templates/layer/mixins/backdropBlur.js:
--------------------------------------------------------------------------------
1 | export default ({ backdropBlur }) => {
2 | if (!backdropBlur) return ""
3 |
4 | if (typeof backdropBlur === "boolean") return `backdrop-filter: blur(10px);`
5 |
6 | return typeof backdropBlur === "number"
7 | ? `backdrop-filter: blur(${backdropBlur}px);`
8 | : `backdrop-filter: blur(${backdropBlur});`
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/templates/layer/mixins/backdropBlur.test.js:
--------------------------------------------------------------------------------
1 | import backdropBlurMixin from "./backdropBlur"
2 |
3 | it("renders", () => {
4 | expect(backdropBlurMixin({})).toBe("")
5 | })
6 |
7 | it("renders boolean backdrop blur", () => {
8 | expect(backdropBlurMixin({ backdropBlur: true })).toBe("backdrop-filter: blur(10px);")
9 | })
10 |
11 | it("renders number backdrop blur", () => {
12 | expect(backdropBlurMixin({ backdropBlur: 10 })).toBe("backdrop-filter: blur(10px);")
13 | })
14 |
15 | it("renders string backdrop blur", () => {
16 | expect(backdropBlurMixin({ backdropBlur: "10px" })).toBe("backdrop-filter: blur(10px);")
17 | })
18 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/alignContent.js:
--------------------------------------------------------------------------------
1 | const alignContentMap = {
2 | start: "flex-start",
3 | center: "center",
4 | end: "flex-end",
5 | between: "space-between",
6 | around: "space-around",
7 | stretch: "stretch",
8 | }
9 |
10 | export default ({ alignContent }) =>
11 | alignContent in alignContentMap ? `align-content: ${alignContentMap[alignContent]};` : ""
12 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/alignContent.test.js:
--------------------------------------------------------------------------------
1 | import alignContent from "./alignContent"
2 |
3 | it("renders", () => {
4 | expect(alignContent({})).toBe("")
5 | })
6 |
7 | it("align content start", () => {
8 | expect(alignContent({ alignContent: "start" })).toBe("align-content: flex-start;")
9 | })
10 |
11 | it("align content invalid", () => {
12 | expect(alignContent({ alignContent: "invalid" })).toBe("")
13 | })
14 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/alignItems.js:
--------------------------------------------------------------------------------
1 | const alignItemValuesMap = {
2 | start: "flex-start",
3 | center: "center",
4 | end: "flex-end",
5 | baseline: "baseline",
6 | stretch: "stretch",
7 | }
8 |
9 | export default ({ alignItems }) =>
10 | alignItems in alignItemValuesMap ? `align-items: ${alignItemValuesMap[alignItems]};` : ""
11 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/alignItems.test.js:
--------------------------------------------------------------------------------
1 | import alignItems from "./alignItems"
2 |
3 | it("renders", () => {
4 | expect(alignItems({})).toBe("")
5 | })
6 |
7 | it("align content start", () => {
8 | expect(alignItems({ alignItems: "end" })).toBe("align-items: flex-end;")
9 | })
10 |
11 | it("align content invalid", () => {
12 | expect(alignItems({ alignItems: "invalid" })).toBe("")
13 | })
14 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/background.js:
--------------------------------------------------------------------------------
1 | import { getColor, getRgbColor } from "@/theme"
2 |
3 | export default ({ theme, background, backgroundOpacity }) => {
4 | if (!background) return ""
5 |
6 | const value = backgroundOpacity
7 | ? getRgbColor(background, backgroundOpacity)({ theme })
8 | : getColor(background)({ theme })
9 |
10 | return value && `background-color: ${value};`
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/background.test.js:
--------------------------------------------------------------------------------
1 | import { DefaultTheme as theme } from "@/theme/default"
2 | import background from "./background"
3 |
4 | it("renders", () => {
5 | expect(background({ theme })).toBe("")
6 | })
7 |
8 | it("renders color", () => {
9 | expect(background({ theme, background: "disabled" })).toBe(
10 | `background-color: ${theme.colors.disabled};`
11 | )
12 | })
13 |
14 | it("renders invalid color", () => {
15 | expect(background({ theme, background: "invalid" })).toBe(`background-color: invalid;`)
16 | })
17 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/direction.js:
--------------------------------------------------------------------------------
1 | const getDirection = (column, columnReverse, rowReverse) => {
2 | if (column) {
3 | return "column"
4 | }
5 |
6 | if (columnReverse) {
7 | return "column-reverse"
8 | }
9 |
10 | if (rowReverse) {
11 | return "row-reverse"
12 | }
13 |
14 | return "row"
15 | }
16 |
17 | export default ({ column, columnReverse, rowReverse }) => {
18 | const direction = getDirection(column, columnReverse, rowReverse)
19 | return `flex-direction: ${direction};`
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/direction.test.js:
--------------------------------------------------------------------------------
1 | import direction from "./direction"
2 |
3 | it("renders", () => {
4 | expect(direction({})).toBe("flex-direction: row;")
5 | })
6 |
7 | it("renders column", () => {
8 | expect(direction({ column: true })).toBe("flex-direction: column;")
9 | })
10 |
11 | it("renders column reverse", () => {
12 | expect(direction({ columnReverse: true })).toBe("flex-direction: column-reverse;")
13 | })
14 |
15 | it("renders row reverse", () => {
16 | expect(direction({ rowReverse: true })).toBe("flex-direction: row-reverse;")
17 | })
18 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/gap.js:
--------------------------------------------------------------------------------
1 | const makeDirection = ({ column, columnReverse, rowReverse }) => {
2 | return column || columnReverse ? "bottom" : rowReverse ? "left" : "right"
3 | }
4 | export default ({
5 | theme: {
6 | constants: { SIZE_SUB_UNIT: baseUnit },
7 | },
8 | gap,
9 | column,
10 | columnReverse,
11 | rowReverse,
12 | }) => {
13 | if (typeof gap !== "number") {
14 | return ""
15 | }
16 |
17 | const direction = makeDirection({ column, columnReverse, rowReverse })
18 | return `
19 | &> *:not(:last-child) {
20 | margin-${direction}: ${baseUnit * gap}px;
21 | }
22 | `
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/height.js:
--------------------------------------------------------------------------------
1 | export default ({
2 | theme: {
3 | constants: { SIZE_SUB_UNIT: baseUnit },
4 | },
5 | height,
6 | }) => {
7 | if (typeof height === "object") {
8 | const { min = "", max = "" } = height
9 | return `
10 | ${min && `min-height: ${typeof min === "number" ? `${baseUnit * min}px` : min};`}
11 | ${max && `max-height: ${typeof max === "number" ? `${baseUnit * max}px` : max};`}
12 | `
13 | }
14 |
15 | return height && `height: ${typeof height === "number" ? `${baseUnit * height}px` : height};`
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/justifyContent.js:
--------------------------------------------------------------------------------
1 | const justifyContentMap = {
2 | start: "start",
3 | center: "center",
4 | end: "end",
5 | between: "space-between",
6 | around: "space-around",
7 | evenly: "space-evenly",
8 | stretch: "stretch",
9 | }
10 |
11 | export default ({ justifyContent }) =>
12 | justifyContent in justifyContentMap
13 | ? `justify-content: ${justifyContentMap[justifyContent]};`
14 | : ""
15 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/justifyContent.test.js:
--------------------------------------------------------------------------------
1 | import justifyContent from "./justifyContent"
2 |
3 | it("renders", () => {
4 | expect(justifyContent({})).toBe("")
5 | })
6 |
7 | it("renders between", () => {
8 | expect(justifyContent({ justifyContent: "between" })).toBe("justify-content: space-between;")
9 | })
10 |
11 | it("renders invalid", () => {
12 | expect(justifyContent({ justifyContent: "invalid" })).toBe("")
13 | })
14 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/overflow.js:
--------------------------------------------------------------------------------
1 | export default ({ overflow }) => {
2 | if (!overflow) {
3 | return ""
4 | }
5 |
6 | if (typeof overflow === "string") {
7 | return `overflow: ${overflow};`
8 | }
9 |
10 | const { vertical = "", horizontal = "" } = overflow
11 | return `
12 | ${vertical && `overflow-y: ${vertical};`}
13 | ${horizontal && `overflow-x: ${horizontal};`}
14 | `
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/overflow.test.js:
--------------------------------------------------------------------------------
1 | import overflow from "./overflow"
2 |
3 | it("renders", () => {
4 | expect(overflow({})).toBe("")
5 | })
6 |
7 | it("renders overflow", () => {
8 | expect(overflow({ overflow: "scroll" })).toBe("overflow: scroll;")
9 | })
10 |
11 | it("renders overflow vertical", () => {
12 | expect(overflow({ overflow: { vertical: "scroll" } }).trim()).toBe("overflow-y: scroll;")
13 | })
14 |
15 | it("renders overflow horizontal", () => {
16 | expect(overflow({ overflow: { horizontal: "scroll" } }).trim()).toBe("overflow-x: scroll;")
17 | })
18 |
19 | it("renders overflow both axis", () => {
20 | expect(overflow({ overflow: { horizontal: "scroll", vertical: "auto" } })).toBe(`
21 | overflow-y: auto;
22 | overflow-x: scroll;
23 | `)
24 | })
25 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/pseudos.test.js:
--------------------------------------------------------------------------------
1 | import pseudos, { pseudoSelectors } from "./pseudos"
2 | import { DefaultTheme as theme } from "@/theme/default"
3 |
4 | const disabledColor = theme.colors.disabled
5 | it("renders", () => {
6 | expect(pseudos({ theme })).toBe("")
7 | })
8 |
9 | it("render border (hover)", () => {
10 | const _hover = { border: { color: "disabled", side: "top", size: "1rem", type: "dashed" } }
11 | const pseudo = `
12 | ${pseudoSelectors["_hover"]}{
13 | border-top: 1rem dashed ${disabledColor};
14 | }`
15 |
16 | expect(pseudos({ theme, _hover })).toBe(pseudo)
17 | })
18 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/width.js:
--------------------------------------------------------------------------------
1 | export default ({
2 | theme: {
3 | constants: { SIZE_SUB_UNIT: baseUnit },
4 | },
5 | width,
6 | }) => {
7 | if (typeof width === "object") {
8 | const { min = "", max = "", base = "" } = width
9 | return `
10 | ${min && `min-width: ${typeof min === "number" ? `${baseUnit * min}px` : min};`}
11 | ${max && `max-width: ${typeof max === "number" ? `${baseUnit * max}px` : max};`}
12 | ${base && `width: ${typeof base === "number" ? `${baseUnit * base}px` : base};`}
13 | `
14 | }
15 |
16 | return width && `width: ${typeof width === "number" ? `${baseUnit * width}px` : width};`
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/wrap.js:
--------------------------------------------------------------------------------
1 | const getWrap = flexWrap => {
2 | if (flexWrap === true) {
3 | return "wrap"
4 | }
5 |
6 | if (flexWrap === false) {
7 | return "nowrap"
8 | }
9 |
10 | return flexWrap === "reverse" ? flexWrap : ""
11 | }
12 |
13 | export default ({ flexWrap }) => {
14 | const value = getWrap(flexWrap)
15 | return value && `flex-wrap: ${value};`
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/templates/mixins/wrap.test.js:
--------------------------------------------------------------------------------
1 | import wrap from "./wrap"
2 |
3 | it("renders", () => {
4 | expect(wrap({})).toBe("")
5 | })
6 |
7 | it("renders wrap", () => {
8 | expect(wrap({ flexWrap: true })).toBe("flex-wrap: wrap;")
9 | })
10 |
11 | it("renders nowrap", () => {
12 | expect(wrap({ flexWrap: false })).toBe("flex-wrap: nowrap;")
13 | })
14 |
15 | it("renders reverse", () => {
16 | expect(wrap({ flexWrap: "reverse" })).toBe("flex-wrap: reverse;")
17 | })
18 |
19 | it("renders invalid", () => {
20 | expect(wrap({ flexWrap: "invalid" })).toBe("")
21 | })
22 |
--------------------------------------------------------------------------------
/src/components/toggle/index.js:
--------------------------------------------------------------------------------
1 | export { Toggle } from "./toggle"
2 |
--------------------------------------------------------------------------------
/src/components/toggle/toggle.d.ts:
--------------------------------------------------------------------------------
1 | import { FC, ReactNode } from "react"
2 | import { AlignSelfProps, MarginProps } from "@/mixins/types"
3 |
4 | export interface ToggleProps extends AlignSelfProps, MarginProps {
5 | checked: boolean
6 | className?: string
7 | colored?: boolean
8 | "data-testid"?: string
9 | disabled?: boolean
10 | Label: ReactNode
11 | labelLeft?: string
12 | labelRight?: string
13 | [s: string]: any
14 | }
15 |
16 | declare const Toggle: FC
17 |
18 | export { Toggle }
19 |
20 | export default Toggle
21 |
--------------------------------------------------------------------------------
/src/components/typography/list.js:
--------------------------------------------------------------------------------
1 | import styled, { css } from "styled-components"
2 | import alignSelf from "@/mixins/alignSelf"
3 | import margin from "@/mixins/margin"
4 | import padding from "@/mixins/padding"
5 |
6 | const list = css`
7 | ${alignSelf}
8 | ${margin}
9 | ${padding}
10 | `
11 |
12 | export const List = styled.ul`
13 | list-style-type: disc;
14 | list-style-position: outside;
15 | padding-left: 28px;
16 | ${list}
17 | `
18 |
19 | export const ListItem = styled.li`
20 | line-height: 22px;
21 | padding-left: 9px;
22 | ${list}
23 | `
24 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/index.d.ts:
--------------------------------------------------------------------------------
1 | export interface TextAlignType {
2 | textAlign?: "left" | "center" | "right"
3 | }
4 |
5 | export interface TextDecorationType {
6 | textDecoration?: "underline" | "none" | "line-through"
7 | }
8 |
9 | export interface TruncateType {
10 | truncate?: boolean
11 | }
12 |
13 | export interface WhiteSpaceProps {
14 | whiteSpace?: "normal" | "nowrap" | "pre-line"
15 | }
16 |
17 | export interface WordBreakProps {
18 | wordBreak?: "normal" | "break-all" | "keep-all" | "break-word"
19 | }
20 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/textAlign.js:
--------------------------------------------------------------------------------
1 | const textAligns = new Set(["left", "center", "right"])
2 |
3 | export default ({ textAlign }) => textAligns.has(textAlign) && `text-align: ${textAlign};`
4 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/textAlign.test.js:
--------------------------------------------------------------------------------
1 | import textAlign from "./textAlign"
2 |
3 | it("renders nothing", () => {
4 | expect(textAlign({})).toBe(false)
5 | })
6 |
7 | it("aligns left", () => {
8 | expect(textAlign({ textAlign: "left" })).toBe("text-align: left;")
9 | })
10 |
11 | it("aligns center", () => {
12 | expect(textAlign({ textAlign: "center" })).toBe("text-align: center;")
13 | })
14 |
15 | it("aligns right", () => {
16 | expect(textAlign({ textAlign: "right" })).toBe("text-align: right;")
17 | })
18 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/textDecoration.js:
--------------------------------------------------------------------------------
1 | const textDecorations = new Set(["underline", "none", "line-through"])
2 |
3 | export default ({ textDecoration }) => textDecorations.has(textDecoration) && `text-decoration: ${textDecoration};`
4 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/textDecoration.test.js:
--------------------------------------------------------------------------------
1 | import textDecoration from "./textDecoration"
2 |
3 | it("renders nothing", () => {
4 | expect(textDecoration({})).toBe(false)
5 | })
6 |
7 | it("decorates with underline", () => {
8 | expect(textDecoration({ textDecoration: "underline" })).toBe("text-decoration: underline;")
9 | })
10 |
11 | it("decorates with none", () => {
12 | expect(textDecoration({ textDecoration: "none" })).toBe("text-decoration: none;")
13 | })
14 |
15 | it("decorates with line-through", () => {
16 | expect(textDecoration({ textDecoration: "line-through" })).toBe("text-decoration: line-through;")
17 | })
18 |
19 | it("doesnt decorate on invalid value", () => {
20 | expect(textDecoration({ textDecoration: "funny-decoration" })).toBe(false)
21 | })
22 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/truncate.js:
--------------------------------------------------------------------------------
1 | export default ({ truncate }) =>
2 | truncate &&
3 | `
4 | white-space: nowrap;
5 | text-overflow: ellipsis;
6 | overflow: hidden;
7 | `
8 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/truncate.test.js:
--------------------------------------------------------------------------------
1 | import truncate from "./truncate"
2 |
3 | it("renders nothing", () => {
4 | expect(truncate({})).toBe(undefined)
5 | })
6 |
7 | it("renders truncate", () => {
8 | expect(truncate({ truncate: true })).toBe(`
9 | white-space: nowrap;
10 | text-overflow: ellipsis;
11 | overflow: hidden;
12 | `)
13 | })
14 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/whiteSpace.js:
--------------------------------------------------------------------------------
1 | const values = new Set(["normal", "nowrap", "pre-line", "pre-wrap"])
2 |
3 | export default ({ whiteSpace }) => values.has(whiteSpace) && `white-space: ${whiteSpace};`
4 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/whiteSpace.test.js:
--------------------------------------------------------------------------------
1 | import whiteSpace from "./whiteSpace"
2 |
3 | it("renders nothing", () => {
4 | expect(whiteSpace({})).toBe(false)
5 | })
6 |
7 | it("renders normal", () => {
8 | expect(whiteSpace({ whiteSpace: "normal" })).toBe("white-space: normal;")
9 | })
10 |
11 | it("renders nowrap", () => {
12 | expect(whiteSpace({ whiteSpace: "nowrap" })).toBe("white-space: nowrap;")
13 | })
14 |
15 | it("renders pre-line", () => {
16 | expect(whiteSpace({ whiteSpace: "pre-line" })).toBe("white-space: pre-line;")
17 | })
18 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/wordBreak.js:
--------------------------------------------------------------------------------
1 | const wordBreaks = new Set(["normal", "break-all", "keep-all", "break-word"])
2 |
3 | export default ({ wordBreak }) => wordBreaks.has(wordBreak) && `word-break: ${wordBreak};`
4 |
--------------------------------------------------------------------------------
/src/components/typography/mixins/wordBreak.test.js:
--------------------------------------------------------------------------------
1 | import wordBreak from "./wordBreak"
2 |
3 | it("renders nothing", () => {
4 | expect(wordBreak({})).toBe(false)
5 | })
6 |
7 | it("renders normal", () => {
8 | expect(wordBreak({ wordBreak: "normal" })).toBe("word-break: normal;")
9 | })
10 |
11 | it("renders break-all", () => {
12 | expect(wordBreak({ wordBreak: "break-all" })).toBe("word-break: break-all;")
13 | })
14 |
15 | it("renders keep-all", () => {
16 | expect(wordBreak({ wordBreak: "keep-all" })).toBe("word-break: keep-all;")
17 | })
18 |
19 | it("renders break-word", () => {
20 | expect(wordBreak({ wordBreak: "break-word" })).toBe("word-break: break-word;")
21 | })
22 |
--------------------------------------------------------------------------------
/src/global-styles.js:
--------------------------------------------------------------------------------
1 | import { createGlobalStyle } from "styled-components"
2 |
3 | export const GlobalStyles = createGlobalStyle`
4 | body {
5 | font-family: "IBM Plex Sans", sans-serif;
6 | background-color: ${props => props.theme.colors.mainBackground};
7 | }
8 | * {
9 | box-sizing: border-box;
10 | }
11 | `
12 |
--------------------------------------------------------------------------------
/src/hooks/useColor/index.js:
--------------------------------------------------------------------------------
1 | import { ThemeContext } from "styled-components"
2 | import { useContext } from "react"
3 | import { getColor } from "@/theme"
4 |
5 | const useColor = () => {
6 | const theme = useContext(ThemeContext)
7 | const pickColor = color => getColor(color)({ theme })
8 |
9 | return pickColor
10 | }
11 |
12 | export default useColor
13 |
--------------------------------------------------------------------------------
/src/hooks/useColor/index.test.js:
--------------------------------------------------------------------------------
1 | import { renderHookWithProviders } from "testUtilities"
2 | import useColor from "./index"
3 |
4 | describe("useColor", () => {
5 | it("should return the desired color", () => {
6 | const colorToReturn = "primary"
7 | const expetedColorHexCode = "#00AB44"
8 |
9 | const { result } = renderHookWithProviders(() => useColor(), {})
10 |
11 | expect(result.current(colorToReturn)).toBe(expetedColorHexCode)
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/src/hooks/useDebounce/index.js:
--------------------------------------------------------------------------------
1 | import { useLayoutEffect, useEffect, useRef } from "react"
2 |
3 | export default (callback, delay, deps = []) => {
4 | const savedCallback = useRef(callback)
5 |
6 | useLayoutEffect(() => {
7 | savedCallback.current = callback
8 | }, deps)
9 |
10 | useEffect(() => {
11 | const id = setTimeout(() => savedCallback.current(), delay)
12 |
13 | return () => clearTimeout(id)
14 | }, [delay, ...deps])
15 | }
16 |
--------------------------------------------------------------------------------
/src/hooks/useDebouncedValue/index.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 | import useDebounce from "../useDebounce"
3 |
4 | export default (value, delay, deps = []) => {
5 | const [state, setState] = useState()
6 |
7 | useDebounce(() => setState(value), delay, [value, ...deps])
8 |
9 | return state
10 | }
11 |
--------------------------------------------------------------------------------
/src/hooks/useDropElement/index.js:
--------------------------------------------------------------------------------
1 | import { useLayoutEffect, useMemo } from "react"
2 |
3 | export default () => {
4 | const el = useMemo(() => {
5 | const div = document.createElement("div")
6 | document.body.append(div)
7 | return div
8 | }, [])
9 |
10 | useLayoutEffect(() => {
11 | return () => {
12 | try {
13 | document.body.removeChild(el)
14 | } catch (e) {
15 | // Do nothing
16 | }
17 | }
18 | }, [])
19 |
20 | return el
21 | }
22 |
--------------------------------------------------------------------------------
/src/hooks/useDropElement/index.test.js:
--------------------------------------------------------------------------------
1 | import { renderHookWithProviders } from "testUtilities"
2 | import useDropElement from "./index"
3 |
4 | it("renders", () => {
5 | const { result } = renderHookWithProviders(useDropElement)
6 | expect(result.current.parentNode).toBe(document.body)
7 | })
8 |
--------------------------------------------------------------------------------
/src/hooks/useForwardRef/index.js:
--------------------------------------------------------------------------------
1 | import { useRef, useCallback } from "react"
2 | import setRef from "@/mixins/set-ref"
3 |
4 | export default ref => {
5 | const innerRef = useRef()
6 |
7 | const forwardRef = useCallback(node => {
8 | innerRef.current = node
9 | setRef(ref, node)
10 | }, [])
11 |
12 | return [innerRef, forwardRef]
13 | }
14 |
--------------------------------------------------------------------------------
/src/hooks/useKeyboardEsc/index.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react"
2 |
3 | const ESC = 27
4 |
5 | export default onEsc =>
6 | useEffect(() => {
7 | if (!onEsc) return
8 |
9 | const onKeydown = event => {
10 | if (event.keyCode === ESC) {
11 | onEsc(event)
12 | }
13 | }
14 |
15 | document.addEventListener("keydown", onKeydown)
16 | return () => document.removeEventListener("keydown", onKeydown)
17 | }, [onEsc])
18 |
--------------------------------------------------------------------------------
/src/hooks/useMountedRef/index.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from "react"
2 |
3 | export default () => {
4 | const mountedRef = useRef(false)
5 |
6 | useEffect(() => {
7 | mountedRef.current = true
8 | return () => (mountedRef.current = false)
9 | }, [])
10 |
11 | return mountedRef
12 | }
13 |
--------------------------------------------------------------------------------
/src/hooks/usePrevious/index.js:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from "react"
2 |
3 | export default (value, distinct = false) => {
4 | const prevRef = useRef()
5 |
6 | useEffect(() => {
7 | prevRef.current = value
8 | }, [distinct ? value : ""])
9 |
10 | return prevRef.current
11 | }
12 |
--------------------------------------------------------------------------------
/src/hooks/useUpdateEffect/index.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react"
2 | import useMountedRef from "@/hooks/useMountedRef"
3 |
4 | export default (cb, deps) => {
5 | const mountedRef = useMountedRef()
6 |
7 | useEffect(() => {
8 | if (!mountedRef.current) return
9 |
10 | return cb()
11 | }, deps)
12 | }
13 |
--------------------------------------------------------------------------------
/src/media.js:
--------------------------------------------------------------------------------
1 | export const devices = {
2 | mobileSmall: "320px",
3 | mobile: "425px",
4 | tablet: "768px",
5 | laptop: "1024px",
6 | laptopLarge: "1200px",
7 | desktop: "1440px",
8 | desktopLarge: "2560px",
9 | }
10 |
11 | export const breakpoints = {
12 | mobileSmall: `(min-width: ${devices.mobileSmall})`,
13 | mobile: `(min-width: ${devices.mobile})`,
14 | tablet: `(min-width: ${devices.tablet})`,
15 | laptop: `(min-width: ${devices.laptop})`,
16 | laptopLarge: `(min-width: ${devices.laptopLarge})`,
17 | desktop: `(min-width: ${devices.desktop})`,
18 | desktopLarge: `(min-width: ${devices.desktopLarge})`,
19 | }
20 |
--------------------------------------------------------------------------------
/src/mixins/alignSelf.js:
--------------------------------------------------------------------------------
1 | const alignSelfMap = {
2 | end: "flex-end",
3 | start: "flex-start",
4 | center: "center",
5 | stretch: "stretch",
6 | }
7 |
8 | export default ({ alignSelf }) =>
9 | alignSelf in alignSelfMap && `align-self: ${alignSelfMap[alignSelf]};`
10 |
--------------------------------------------------------------------------------
/src/mixins/alignSelf.test.js:
--------------------------------------------------------------------------------
1 | import alignSelf from "./alignSelf"
2 |
3 | it("renders nothing", () => {
4 | expect(alignSelf({})).toBe(false)
5 | })
6 |
7 | it("renders start", () => {
8 | expect(alignSelf({ alignSelf: "start" })).toBe("align-self: flex-start;")
9 | })
10 |
11 | it("renders center", () => {
12 | expect(alignSelf({ alignSelf: "center" })).toBe("align-self: center;")
13 | })
14 |
15 | it("renders end", () => {
16 | expect(alignSelf({ alignSelf: "end" })).toBe("align-self: flex-end;")
17 | })
18 |
19 | it("renders stretch", () => {
20 | expect(alignSelf({ alignSelf: "stretch" })).toBe("align-self: stretch;")
21 | })
22 |
--------------------------------------------------------------------------------
/src/mixins/controlFocused.js:
--------------------------------------------------------------------------------
1 | import { css } from "styled-components"
2 | import { getValidatedControlColor } from "@/theme"
3 |
4 | export default css`
5 | border-color: ${getValidatedControlColor("controlFocused")};
6 | box-shadow: 0 0 0 1px ${getValidatedControlColor("controlFocused")};
7 | `
8 |
--------------------------------------------------------------------------------
/src/mixins/controlReset.js:
--------------------------------------------------------------------------------
1 | export default `
2 | font-family: inherit;
3 | border: none;
4 | outline: none;
5 | padding: 0;
6 | margin: 0;
7 | `
8 |
--------------------------------------------------------------------------------
/src/mixins/cursor.js:
--------------------------------------------------------------------------------
1 | export default ({ cursor }) => {
2 | if (!cursor) return ""
3 | return `cursor: ${cursor};`
4 | }
5 |
--------------------------------------------------------------------------------
/src/mixins/cursor.test.js:
--------------------------------------------------------------------------------
1 | import cursor from "./cursor"
2 |
3 | describe("cursor", () => {
4 | it("renders nothing", () => {
5 | expect(cursor({})).toBe("")
6 | })
7 |
8 | it("renders cursor: pointer", () => {
9 | expect(cursor({ cursor: "pointer" })).toBe("cursor: pointer;")
10 | })
11 |
12 | it("renders cursor invalid", () => {
13 | expect(cursor({ cursor: "invalid" })).toBe("cursor: invalid;")
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/src/mixins/index.js:
--------------------------------------------------------------------------------
1 | export { default as alignSelf } from "./alignSelf"
2 | export { default as controlFocused } from "./controlFocused"
3 | export { default as controlReset } from "./controlReset"
4 | export { default as cursor } from "./cursor"
5 | export { default as margin } from "./margin"
6 | export { default as opacity } from "./opacity"
7 | export { default as padding } from "./padding"
8 | export { default as position } from "./position"
9 | export { default as round } from "./round"
10 | export { default as textTransform } from "./textTransform"
11 | export { default as webkitVisibleScrollbar } from "./webkitVisibleScrollbar"
12 | export { default as zIndex } from "./zIndex"
13 |
--------------------------------------------------------------------------------
/src/mixins/margin.js:
--------------------------------------------------------------------------------
1 | import { getDimensions } from "@/mixins/utils"
2 |
3 | export default ({ theme, margin }) => {
4 | if (!margin) return ""
5 |
6 | if (Array.isArray(margin) && margin.length >= 1 && margin.length <= 4) {
7 | return `margin: ${getDimensions(theme, margin)};`
8 | }
9 |
10 | // eslint-disable-next-line no-console
11 | console.error("Please provide an array (max 4 elements) for `margin` style helper.")
12 |
13 | return ""
14 | }
15 |
--------------------------------------------------------------------------------
/src/mixins/opacity.js:
--------------------------------------------------------------------------------
1 | const opacityMap = {
2 | weak: 0.3,
3 | medium: 0.4,
4 | strong: 0.8,
5 | none: 1,
6 | }
7 |
8 | export default ({ opacity }) => {
9 | const value = (opacity && opacityMap[opacity]) || opacity
10 | return value ? `opacity: ${value};` : ""
11 | }
12 |
--------------------------------------------------------------------------------
/src/mixins/opacity.test.js:
--------------------------------------------------------------------------------
1 | import styledOpacity from "./opacity"
2 |
3 | it("renders", () => {
4 | expect(styledOpacity({})).toBe("")
5 | })
6 |
7 | it("renders weak opacity", () => {
8 | expect(styledOpacity({ opacity: "weak" })).toBe(`opacity: 0.3;`)
9 | })
10 |
11 | it("renders invalid opacity", () => {
12 | expect(styledOpacity({ opacity: "invalid" })).toBe("opacity: invalid;")
13 | })
14 |
--------------------------------------------------------------------------------
/src/mixins/padding.js:
--------------------------------------------------------------------------------
1 | import { getDimensions } from "@/mixins/utils"
2 |
3 | export default ({ theme, padding }) => {
4 | if (!padding) return ""
5 |
6 | if (Array.isArray(padding) && padding.length >= 1 && padding.length <= 4) {
7 | return `padding: ${getDimensions(theme, padding)};`
8 | }
9 |
10 | // eslint-disable-next-line no-console
11 | console.error("Please provide an array (max 4 elements) for `padding` style helper.")
12 |
13 | return ""
14 | }
15 |
--------------------------------------------------------------------------------
/src/mixins/position.js:
--------------------------------------------------------------------------------
1 | const positionMap = {
2 | static: "static",
3 | absolute: "absolute",
4 | fixed: "fixed",
5 | relative: "relative",
6 | sticky: "sticky",
7 | initial: "initial",
8 | inherit: "inherit",
9 | }
10 |
11 | export default ({ position }) => {
12 | return position in positionMap ? `position: ${position};` : ""
13 | }
14 |
--------------------------------------------------------------------------------
/src/mixins/position.test.js:
--------------------------------------------------------------------------------
1 | import position from "./position"
2 |
3 | it("renders", () => {
4 | expect(position({})).toBe("")
5 | })
6 |
7 | it("renders relative position", () => {
8 | expect(position({ position: "relative" })).toBe(`position: relative;`)
9 | })
10 |
11 | it("renders position invalid", () => {
12 | expect(position({ position: "invalid" })).toBe("")
13 | })
14 |
--------------------------------------------------------------------------------
/src/mixins/set-ref/index.js:
--------------------------------------------------------------------------------
1 | export default (ref, node) => {
2 | if (typeof ref === "function") {
3 | ref(node)
4 | } else if (ref) {
5 | ref.current = node
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/mixins/textTransform.js:
--------------------------------------------------------------------------------
1 | const textTransformMap = {
2 | none: "none",
3 | capitalize: "capitalize",
4 | uppercase: "uppercase",
5 | lowercase: "lowercase",
6 | firstLetter: "firstLetter",
7 | fullWidth: "full-width",
8 | }
9 |
10 | const textTransform = ({ textTransform = textTransformMap.none } = {}) => {
11 | if (textTransform === textTransformMap.firstLetter)
12 | return `text-transform: lowercase;
13 | &::first-letter {
14 | text-transform: uppercase;
15 | }
16 | `
17 | return textTransform in textTransformMap
18 | ? `text-transform: ${textTransformMap[textTransform]};`
19 | : `text-transform: ${textTransformMap.none};`
20 | }
21 |
22 | export default textTransform
23 |
--------------------------------------------------------------------------------
/src/mixins/utils.js:
--------------------------------------------------------------------------------
1 | const getUnit = value => (value === 0 ? "0" : `${value}px`)
2 |
3 | export const getDimension = (theme, size) =>
4 | typeof size === "number" ? getUnit(theme.constants.SIZE_SUB_UNIT * size) : "auto"
5 |
6 | export const getDimensions = (theme, value) =>
7 | value.map(size => getDimension(theme, size)).join(" ")
8 |
--------------------------------------------------------------------------------
/src/mixins/uuid/index.js:
--------------------------------------------------------------------------------
1 | let counter = 0
2 |
3 | export default () => --counter
4 |
--------------------------------------------------------------------------------
/src/mixins/uuid/index.test.js:
--------------------------------------------------------------------------------
1 | import getUUID from './index';
2 |
3 | it('returns a negative number', async () => {
4 | expect(getUUID()).toBeLessThan(0);
5 | });
6 |
7 | it('returns progressively decreasing numbers', async () => {
8 | const first = getUUID();
9 | const sec = getUUID();
10 | const third = getUUID();
11 | expect(third).toBeLessThan(sec);
12 | expect(sec).toBeLessThan(first);
13 | expect(first).toBeLessThan(0);
14 | });
15 |
--------------------------------------------------------------------------------
/src/mixins/zIndex.js:
--------------------------------------------------------------------------------
1 | export default ({ zIndex }) => {
2 | if (!zIndex) return
3 | if (typeof zIndex !== "number") return
4 | return `z-index: ${zIndex};`
5 | }
6 |
--------------------------------------------------------------------------------
/src/mixins/zIndex.test.js:
--------------------------------------------------------------------------------
1 | import zIndex from "./zIndex"
2 |
3 | it("renders", () => {
4 | expect(zIndex({})).toBe(undefined)
5 | })
6 |
7 | it("renders z-index", () => {
8 | expect(zIndex({ zIndex: 1000 })).toBe("z-index: 1000;")
9 | })
10 |
11 | it("renders invalid z-index", () => {
12 | expect(zIndex({ zIndex: "invalid" })).toBe(undefined)
13 | })
14 |
--------------------------------------------------------------------------------
/src/organisms/documentation/README.md:
--------------------------------------------------------------------------------
1 | ## Documentation Help Button
2 |
3 | An organism that creates a fixed button on the bottom right of the screen, that on click opens a drop that has documentation links.
4 |
5 | ### Props:
6 |
7 | ```typescript
8 | export interface DocumentationProps {
9 | app?: "cloud" | "agent"
10 | children: (toggle: () => void, isOpen: boolean) => ReactNode
11 | }
12 | ```
13 |
14 | ### Typical usage:
15 |
16 | ```JSX
17 | export const Container = () => {
18 | return (
19 |
20 | {(toggle, isOpen) => (
21 |
22 | )}
23 |
24 | )
25 | }
26 | ```
27 |
--------------------------------------------------------------------------------
/src/organisms/documentation/dashboard/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import styled from "styled-components"
3 | import { Tabs, Tab } from "@/components/tabs"
4 | import Flex from "@/components/templates/flex"
5 | import Mouse from "./mouse"
6 | import Touch from "./touch"
7 |
8 | const StyledTabs = styled(Tabs)`
9 | width: 100%;
10 |
11 | .tabs > * {
12 | min-width: initial;
13 | max-width: initial;
14 | }
15 | `
16 |
17 | const Dashboard = () => (
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | )
29 |
30 | export default Dashboard
31 |
--------------------------------------------------------------------------------
/src/organisms/documentation/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react"
2 |
3 | export interface DocumentationProps {
4 | app?: "cloud" | "agent"
5 | onClickOut?: () => void
6 | onCloseClick?: () => void
7 | onVisitDocumentClick?: () => void
8 | onOpenIssueClick?: () => void
9 | onOpenBugClick?: () => void
10 | onContributeClick?: () => void
11 | onSupportClick?: () => void
12 | children: (toggle: () => void, isOpen: boolean) => ReactNode
13 | }
14 |
15 | declare const Documentation: React.FC
16 |
17 | export default Documentation
18 |
--------------------------------------------------------------------------------
/src/organisms/documentation/search/discourse/index.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react"
2 | import fetchTopics from "./api"
3 |
4 | const DiscourseSearch = ({ children, ...rest }) => {
5 | const [topics, setTopics] = useState([])
6 |
7 | const { searchTerm, results } = rest
8 |
9 | useEffect(() => {
10 | if (!searchTerm) return
11 |
12 | let isSubscribed = true
13 | const onSuccess = ({ data }) => isSubscribed && setTopics(data)
14 |
15 | fetchTopics(searchTerm, onSuccess)
16 | return () => (isSubscribed = false)
17 | }, [searchTerm])
18 |
19 | return children({ ...rest, results: { ...results, discourse: topics } })
20 | }
21 |
22 | export default DiscourseSearch
23 |
--------------------------------------------------------------------------------
/src/organisms/documentation/search/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./provider"
2 | export { default as SearchInput } from "./input"
3 | export { default as SearchResults } from "./results"
4 |
--------------------------------------------------------------------------------
/src/organisms/documentation/search/utils.js:
--------------------------------------------------------------------------------
1 | const domainRegexp = /^https:\/\/((learn.netdata).cloud|www.(netdata.cloud)|github.com\/netdata\/(netdata-cloud)|github.com\/netdata\/(netdata))/
2 |
3 | export const getResultsByKey = results => {
4 | return results.reduce((acc, result) => {
5 | const matched = result.url.raw.match(domainRegexp)
6 | const key = matched.find((s, i) => i > 1 && s)
7 | acc[key] = acc[key] || []
8 | acc[key].push(result)
9 | return acc
10 | }, {})
11 | }
12 |
--------------------------------------------------------------------------------
/src/organisms/navigation/hooks/useNavigationScroll.js:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect } from "react"
2 |
3 | export default ref => {
4 | const onWheel = useCallback(e => {
5 | const container = ref.current
6 | container.scrollLeft = container.scrollLeft + e.deltaY * 0.1
7 | })
8 |
9 | useEffect(() => {
10 | if (!ref.current) return
11 | const container = ref.current
12 | container.addEventListener("wheel", onWheel)
13 | return () => container.remove("wheel", onWheel)
14 | }, [])
15 | }
16 |
--------------------------------------------------------------------------------
/src/organisms/navigation/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react"
2 |
3 | export interface TabbedNavigationProps {
4 | children: ReactNode
5 | }
6 | declare const TabbedNavigation: React.FC
7 |
8 | export default TabbedNavigation
9 |
--------------------------------------------------------------------------------
/src/organisms/navigation/index.js:
--------------------------------------------------------------------------------
1 | export { default as Tab } from "./tab"
2 | export { default as Tabs } from "./tabs"
3 | export { default as DraggableTabs, BaseSortable as BaseDraggableTabs } from "./sortable"
4 | export { default as TabSeparator } from "./tab/tabSeparator"
5 | export { default as Sortable } from "./sortable"
6 |
--------------------------------------------------------------------------------
/src/organisms/navigation/sortable/arrow.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import styled from "styled-components"
3 | import Flex from "@/components/templates/flex"
4 | import { Icon } from "@/components/icon/icon"
5 |
6 | const IconWrapper = styled(Flex).attrs(props => ({
7 | height: "100%",
8 | alignItems: "center",
9 | padding: [2],
10 | background: "topBarBg",
11 | position: "absolute",
12 | cursor: "pointer",
13 | sx: props.right ? { right: 0 } : { left: 0 },
14 | zIndex: 3,
15 | ...props,
16 | }))``
17 |
18 | export default ({ onClick, name, right }) => (
19 |
20 |
21 |
22 | )
23 |
--------------------------------------------------------------------------------
/src/organisms/navigation/sortable/container.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components"
2 | import Flex from "@/components/templates/flex"
3 | import { getColor } from "@/theme"
4 |
5 | const Container = styled(Flex).attrs({
6 | width: "100%",
7 | height: "100%",
8 | flex: true,
9 | basis: "0%",
10 | position: "relative",
11 | overflow: { vertical: "hidden", horizontal: "auto" },
12 | alignItems: "center",
13 | })`
14 | -ms-overflow-style: none;
15 | overflow: -moz-scrollbars-none;
16 |
17 | &::-webkit-scrollbar {
18 | height: 0px;
19 | }
20 |
21 | ::-webkit-scrollbar-thumb {
22 | background: ${getColor("selected")};
23 | }
24 | `
25 |
26 | export default Container
27 |
--------------------------------------------------------------------------------
/src/organisms/navigation/tab/tabSeparator.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Flex from "@/components/templates/flex"
3 |
4 | export default () => (
5 |
6 |
7 |
8 | )
9 |
--------------------------------------------------------------------------------
/src/organisms/news/container.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components"
2 | import Flex from "@/components/templates/flex"
3 | import { webkitVisibleScrollbar } from "@/mixins"
4 |
5 | const Container = styled(Flex).attrs({
6 | overflow: { vertical: "auto" },
7 | padding: [0, 4, 0, 0],
8 | })`
9 | ${webkitVisibleScrollbar}
10 | `
11 |
12 | export default Container
13 |
--------------------------------------------------------------------------------
/src/organisms/news/header.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Flex from "@/components/templates/flex"
3 | import { Icon } from "@/components/icon"
4 | import { TextBig } from "@/components/typography"
5 | import { Button } from "@/components/button"
6 |
7 | const Header = ({ onClose }) => {
8 | return (
9 |
15 |
16 |
17 | Netdata News
18 |
19 |
20 |
21 | )
22 | }
23 |
24 | export default Header
25 |
--------------------------------------------------------------------------------
/src/organisms/news/index.d.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react"
2 |
3 | export interface NewsProps {
4 | app?: "cloud" | "agent"
5 | onCloseClick?: () => void
6 | children: (toggle: () => void, isOpen: boolean, upToDate: boolean) => ReactNode
7 | }
8 |
9 | declare const News: React.FC
10 |
11 | export default News
12 |
--------------------------------------------------------------------------------
/src/organisms/news/index.stories.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Pill from "@/components/pill"
3 | import News from "."
4 |
5 | export const CloudNews = () => (
6 |
7 | {({ toggle, upToDate }) => (
8 |
9 | Cloud news
10 |
11 | )}
12 |
13 | )
14 |
15 | export const AgentNews = () => (
16 |
17 | {({ toggle, upToDate }) => (
18 |
19 | Agent news
20 |
21 | )}
22 |
23 | )
24 |
25 | export default {
26 | component: News,
27 | }
28 |
--------------------------------------------------------------------------------
/src/organisms/news/item/anchor.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components"
2 | import Flex from "@/components/templates/flex"
3 |
4 | const Anchor = styled(Flex).attrs({ as: "a" })`
5 | text-decoration: none;
6 | & :hover {
7 | text-decoration: none;
8 | }
9 | `
10 | export default Anchor
11 |
--------------------------------------------------------------------------------
/src/organisms/news/item/image.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components"
2 | import Flex from "@/components/templates/flex"
3 |
4 | const Image = styled(Flex).attrs({ as: "img" })`
5 | object-fit: cover;
6 | `
7 |
8 | export default Image
9 |
--------------------------------------------------------------------------------
/src/organisms/news/useFetchNews.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react"
2 | import * as prismic from "@prismicio/client"
3 |
4 | const getClient = () => prismic.createClient("https://netdata-news.cdn.prismic.io/api/v2")
5 |
6 | export default () => {
7 | const [client] = useState(getClient)
8 |
9 | return (app, onSuccess, onError) =>
10 | client
11 | .get({
12 | filters: [prismic.filter.any("document.tags", Array.isArray(app) ? app : [app])],
13 | pageSize: 100,
14 | orderings: [{ field: "document.last_publication_date", direction: "desc" }],
15 | })
16 | .then(onSuccess)
17 | .catch(onError)
18 | }
19 |
--------------------------------------------------------------------------------
/src/organisms/topbar/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Flex from "@/components/templates/flex"
3 |
4 | const Topbar = ({ extended = false, children, mainChild }) => {
5 | return (
6 |
7 | {mainChild}
8 |
9 | {children}
10 |
11 |
12 | )
13 | }
14 |
15 | export default Topbar
16 |
--------------------------------------------------------------------------------
/src/theme/dark/index.js:
--------------------------------------------------------------------------------
1 | import colors from "./colors"
2 | import * as constants from "../default/constants"
3 |
4 | const root = {
5 | name: "Dark",
6 | version: "0.0.1",
7 | }
8 |
9 | export const DarkTheme = {
10 | ...root,
11 | constants,
12 | colors,
13 | }
14 |
--------------------------------------------------------------------------------
/src/theme/default/constants.js:
--------------------------------------------------------------------------------
1 | // assumed to be in "px"
2 | export const SIZE_SUB_UNIT = 4
3 |
4 | export const SIZE_UNIT = 8
5 |
6 | export const GUTTER_HEIGHT = 8
7 |
--------------------------------------------------------------------------------
/src/theme/default/index.js:
--------------------------------------------------------------------------------
1 | import colors from "./colors"
2 | import * as constants from "./constants"
3 |
4 | const root = {
5 | name: "Default",
6 | version: "0.0.1",
7 | }
8 |
9 | export const DefaultTheme = {
10 | ...root,
11 | constants,
12 | colors,
13 | }
14 |
--------------------------------------------------------------------------------
/src/theme/index.js:
--------------------------------------------------------------------------------
1 | export * from "./default"
2 | export * from "./dark"
3 | export * from "./utils"
4 |
--------------------------------------------------------------------------------
/src/utils/assertions.js:
--------------------------------------------------------------------------------
1 | export function isFunction(value) {
2 | return typeof value === "function"
3 | }
4 |
5 | export function isArray(value) {
6 | return Array.isArray(value)
7 | }
8 |
9 | export function isObject(value) {
10 | const type = typeof value
11 | return value != null && (type === "object" || type === "function") && !isArray(value)
12 | }
13 |
14 | export function isEmptyObject(value) {
15 | return isObject(value) && Object.keys(value).length === 0
16 | }
17 |
--------------------------------------------------------------------------------
/src/utils/capitalizeFirstLetter.js:
--------------------------------------------------------------------------------
1 | const capitalizeFirstLetter = (string, capitalizeOnlyFirst) => {
2 | const word = capitalizeOnlyFirst ? string.toLowerCase() : string
3 | return word.charAt(0).toUpperCase() + word.slice(1)
4 | }
5 |
6 | export default capitalizeFirstLetter
7 |
--------------------------------------------------------------------------------
/src/utils/capitalizeFirstLetter.test.js:
--------------------------------------------------------------------------------
1 | import capitalizeFirstLetter from "./capitalizeFirstLetter"
2 |
3 | describe("capitalizeFirstLetter util", () => {
4 | test("should return string with capitalized first letter", () => {
5 | const result = capitalizeFirstLetter("hello")
6 | expect(result).toEqual("Hello")
7 | })
8 |
9 | test("should return capitalized string with capitalized first letter only", () => {
10 | const result = capitalizeFirstLetter("HELLO", true)
11 | expect(result).toEqual("Hello")
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | export { mergeRefs } from "./mergeRefs"
2 | export * from "./assertions"
3 | export { default as capitalizeFirstLetter } from "./capitalizeFirstLetter"
4 |
--------------------------------------------------------------------------------
/src/utils/mergeRefs.js:
--------------------------------------------------------------------------------
1 | import { isFunction } from "./assertions"
2 |
3 | export function assignRef(ref, value) {
4 | if (ref == null) return
5 |
6 | if (isFunction(ref)) {
7 | ref(value)
8 | return
9 | }
10 |
11 | try {
12 | ref.current = value
13 | } catch (error) {
14 | throw new Error(`Cannot assign value '${value}' to ref '${ref}'`)
15 | }
16 | }
17 |
18 | export function mergeRefs(...refs) {
19 | return node => {
20 | refs.forEach(ref => assignRef(ref, node))
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/utils/useContextSelector/index.js:
--------------------------------------------------------------------------------
1 | import { useRef } from "react"
2 | import identity from "lodash/identity"
3 | import isEqual from "lodash/isEqual"
4 | import { useContextSelector } from "use-context-selector"
5 |
6 | export default (Context, select = identity) => {
7 | const prevRef = useRef()
8 | return useContextSelector(Context, state => {
9 | const selected = select(state)
10 | if (!isEqual(prevRef.current, selected)) prevRef.current = selected
11 | return prevRef.current
12 | })
13 | }
14 |
--------------------------------------------------------------------------------
/utils/index.js:
--------------------------------------------------------------------------------
1 | export { readmeCleanup } from "./readme"
2 |
--------------------------------------------------------------------------------
/utils/readme.js:
--------------------------------------------------------------------------------
1 | export const readmeCleanup = text =>
2 | text.replace('module.exports = "', "").replace(/\\n/g, "\n").replace(/";$/, "")
3 |
--------------------------------------------------------------------------------